Monday, 17 April 2017 10:56

Raspberry Pi - Auto WiFi Hotspot Switch

Written by 
  • Author Type: Individual
  • Country: uk

A script to switch between a WiFi Network or WiFi HotSpot without a reboot. If the Wifi network is lost then the RPi will generate a Wifi hotspot, then reconnect to the Network when it is available again.

This article is not the latest version of the AutoHotspot script, two new versions are now available.

 

 

I often use my Raspberry Pi's in the garden or away from home. I use a script that generates a wifi hotspot if my home network is not found so I can ssh to the Raspberry Pi via my Tablet, Phone or Laptop. When I am at home it will connect to my Home network as normal. This only happens at reboot but works fine for what it is designed for. If I have a Raspberry Pi in my garden taking photos or using sensors it will be connected to my home network but occasionally looses connection to my router and not reconnect probably due to inteferance. This means I have to go outside and reboot the pi to get the wifi back.

I have now updated my original script so that it can switch the RPI between an access point hotspot or network without a reboot. Using this script along with a timer, if the RPi looses connection with the router it will generate a WiFi Hotspot when the timer is triggered so I can still gain SSH or VNC access without going outside.

This can also be used so the Pi will genarally switch between a hotspot or network as you come home from a trip out without rebooting. Though if you have made a ssh or vnc connection at the point it switches you will loose your connection.

This setup is designed to gain direct access to the pi when it is not in range of a network, as a result it will not be able to connect to the Internet via Ethernet in hotspot mode but is fully functional in Network mode. 

Aim: 

  • On bootup it will connect to a known network or if not available generate a hotspot
  • Access available via SSH and VNC in both network and hotspot mode
  • using a timer to run the script at set intervals:
    • If the Raspberry Pi looses network connection it will generate a wifi hotspot
    • When the network is available again RPi reconnects to the router

Can be used for:

  • Running a program in the background when you are home, then when you go out of network range you can still access the Rpi to check results or make changes.
  • Raspberry Pi In car entertainment setups. Upload new content at home from the network then access the pi via a hotspot on the move. Could be altered to allow a button to activate Hotspot or Network manually.
  • Linking a Raspberry Pi with a Laptop and Telescope for photography or positioning.
  • If you use the RPi in your garden and place it in a wifi dead zone, it is still accessible via ssh or vnc in hotspot mode.

 

Requirments

Connection settings already created for any SSID you are using and listed in /etc/wpa_supplicant/wpa_supplicant.conf

The "Raspberry Pi 3 Auto WiFi Spot if no Internet" article has been followed except the /usr/bin/autohotspot script.

Initial Setup

This article makes changes to the main script of Raspberry PI 3 Auto WiFi Hotspot if no Internet

For the full setup follow the instructions in the link above but change the script saved as /usr/bin/autohotspot to the one in this article.

 

Hotspot and Network Switch script

 Once you have setup:

  • Hostapd
  • DnsMasq
  • Made changes to the Interfaces file
  • Set up the systemd autohotspot.service and activated it

Save following script to /usr/bin/autohotspot (last modified 30th May 2017)

(Also available to download from here)


#!/bin/bash
#Script to switch between a wifi network and a No Internet Hotspot without rebooting
#Other setup required find out more at 
#http://www.raspberryconnect.com/network/item/315-raspberry-pi-3-auto-wifi-hotspot-if-no-internet
# These two lines check if any of the wifi networks already setup are in range
wpassid=$(awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=' ' | sed 's/\"/''/g' | sed 's/ $//')
ssids=($wpassid)
#Note:If you only want to check for certain SSids
#Remove the # in in front of ssids=('mySSID1'....  and 
#put a # infront of  ssids=$(awk '..... & ssids($wpassid) in the lines above
# separated by a space, ('mySSID1' 'mySSID2')
#ssids=('mySSID1' 'mySSID2' 'mySSID3')
createAdHocNetwork()
{
    ip link set dev wlan0 down
    ip a add 10.0.0.5/24 dev wlan0
    ip link set dev wlan0 up
    systemctl start dnsmasq
    systemctl start hostapd
}
KillHotspot()
{
	echo "Shutting Down Hotspot"
	ip link set dev wlan0 down
	systemctl stop hostapd
	systemctl stop dnsmasq
	ip addr flush dev wlan0
	ip link set dev wlan0 up
}
#ssid in range check
ssidChk=('NoSSid')
for ssid in "${ssids[@]}"
do 
	if iw dev wlan0 scan ap-force | grep "$ssid" > /dev/null ;then
		ssidChk=$ssid
                break
	else
		ssidChk='NoSSid'
	fi
done 
if [ $ssidChk != "NoSSid" ] 
then
	if systemctl status hostapd | grep "(running)"
	then #hotspot running and ssid in range
		KillHotspot
		echo "Hotspot Deactivated, Bringing Wifi Up"
        	wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf > /dev/null 2>&1
	elif wpa_cli status | grep 'wlan0'
	then #If already connected stop script
		echo "Wifi already connected to network"
	else #ssid exists and no hotspot running connect to wifi network
		echo "Connecting to WiFi Network"
		wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf > /dev/null 2>&1
        	if wpa_cli status | grep 'wlan0' > /dev/null
        	then
			echo "Wifi connection ok"
        	else
			echo "Wifi failed to connect, Creating Hotspot instead"
            		wpa_cli terminate
			createAdHocNetwork
        	fi
	fi
else #ssid not in range
    	if systemctl status hostapd | grep "(running)" > /dev/null 
	then
		echo "Hostspot already active"
	elif wpa_cli status | grep 'wlan0' > /dev/null
	then
		echo "Cleaning wifi files and Activating Hotspot"
		wpa_cli terminate
		ip addr flush wlan0
		ip link set dev wlan0 down
		rm -r /var/run/wpa_supplicant > /dev/null
		createAdHocNetwork
	else #"No SSID, activating Hotspot"
		createAdHocNetwork
	fi
fi

This script works by either checking all wifi networks that you have set a connection to (found in wpa_supplicant.conf) or just checks the WiFi networks you enter a SSID for, and ignores any others you have configured in your wifi settings.

By Default it will just try to connect to any WiFi network you Raspberry Pi has been setup to use.

To only check for certain SSIDs put a # in front of the line starting ssids=$(awk '/s..... and ssids=($wpassid)

and remove the # from the line starting #ssids=('mySSID1......

Change the entries in ssids=('mySSID1' 'mySSID2' 'mySSID3') to your routers SSID you can add or delete ssid entries but make sure there is a space between each entry.

The line that goes off the page reads

wpassid=$(awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=' ' | sed 's/\"/''/g')

(Thanks to Tino for contribution this command)

Once saved make the script executable with

sudo chmod +x /usr/bin/autohotspot

Now the script will only work at bootup so we need to setup a timer to run the autohotspot script at set intervals.

For now I have had to do this using a Cron job as systemd timers are not working consistantly with this to be useful.

Using a Cron job, tasks can be set off automatically at certain times, dates or intervals. For my use running the script every 5 minutes is fine but this can be changed to your needs. To setup a cron task enter the command

crontab -e

At the bottom of the file enter the command

*/5 * * * * sudo /usr/bin/autohotspot

There is a space after each entry and * except the first *.

 The first * position is for minutes. If you want it to check every minute just use * instead of */5

If you want to use hours, say every 2 hours enter it as

* */2 * * * sudo /usr/bin/autohotspot

 Save the cron tab with ctrl & o and close it with ctrl & x

The cron job will automatically start straight away.

 

This process has been tested on a Raspberry Pi 3 and a Raspberry Pi Zero W.

Disable Cron Timer

If you no longer need the timer running edit the cron with

crontab -e

and put a # infront so it is now

#*/5 * * * * sudo /usr/bin/autohotspot

The script will now only work at boot up or if you manually run the autohotspot script with the command

sudo /usr/bin/autohotspot

Script Removal

To disable the complete autohotspot process;

Edit the /etc/network/interfaces file and remove the # from the line

# wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Then disable the startup script with the command

sudo systemctl disable autohotspot

After a reboot your RPi will connect to your router.

 

 Note:

The # infront of wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf in the interfaces file is not required for this script. If your router is in range the system will connect to the router without the script. The autohotspot script will run and make changes when required.

 

Dnsmasq bug: in versions below 2.77 there is a recent bug that may cause the hotspot not to start. This can be resolved by removing the dns-root-data.

check your version with : dpkg -s dnsmasq

versions 2.77 and above are ok. If not then try the command:

sudo apt-get purge dns-root-data

thanks to danny for highlighting this.

Last modified on Saturday, 08 July 2017 11:01
Google
roboberry

RapberryConnect.com SuperUser.  Contactable via the site admin e-mail in the Contact Us link.

Website: www.raspberryconnect.com

Leave a comment

Comments for Guest and account owners. Account owners will need to login to use registered e-mail address.

41 comments

  • Comment Link Graeme Tuesday, 04 July 2017 19:24 posted by Graeme

    Hi Lyndon, If you have the # in front of the wpa_supplicant line in the interfaces file then the script is working or you wouldn't get wifi either, so there could be config issue somewhere.
    If you have removed the # then the autohotspot script is not running.

    To manually run the script enter sudo /usr/bin/autohotspot
    also sudo systemctl status -l autohotspot will give you feed back on when it was last run and any errors.

    I would also check hostapd with sudo systemctl status -l hostapd as this is most likely where the issue is if the autohotspot script is running.

    I have the same version of dnsmasq and had no issues but it may be an issue for some users.

    If you use a screen is the wifi icon two red crosses?

    If you have no luck your welcome to e-mail me more details and I will look into it further.

    I'm about to upgrade the script so keep an eye out for that, it will just replace the current script, but won't resolve your current issue.

    Report
  • Comment Link Lyndon Monday, 03 July 2017 23:50 posted by Lyndon

    Hi, thanks for this great script setup, but I just can't get it to work on my pi Zero W. I have followed everything carefully, but it just won't start hotspot if it can't see a wifi network it knows about.

    I have dnsmasq 2.76-5+rpi1 if that helps and have tried "sudo apt-get purge dns-root-data"

    Is there some where I can see a log file of where its falling over? or start the hotspot manually in the terminal or something to see any errors?

    Thanks for any help

    Report
  • Comment Link Joe Morris Monday, 26 June 2017 03:07 posted by Joe Morris

    Please do. :)

    I would love to see it.

    Report
  • Comment Link Graeme Sunday, 25 June 2017 22:11 posted by Graeme

    Hi Joe. The password issue has been resolved in the new scripts im testing. If no ip has been assigned to the RPi within 10 seconds it will fall back to the hotspot. I have done multiple test on this script and it has been fine so far. I can send you a pre-release copy if that helps, if you need it before I post it to the site?

    Report
  • Comment Link Joe Morris Sunday, 25 June 2017 14:33 posted by Joe Morris

    I left another comment in reference to the password issue.

    Then I read a little more. :)

    I see two possible solutions.

    1. Check for a valid ip address
    2. Ping the gateway provided.

    IS there anything I can do to help prioritize this modification?

    Thanks

    Joe

    Report
  • Comment Link Joe Morris Sunday, 25 June 2017 14:25 posted by Joe Morris

    Graeme,

    Thanks for sending me over here.

    This script looks great. I am concerned about the incorrect password issue mentioned in a previous post. Has that been resolved? I too am creating a retail device and cannot afford to have a dead product just because of a user input error.

    Thanks

    Joe

    Report
  • Comment Link Graeme Tuesday, 13 June 2017 20:44 posted by Graeme

    Hi Scott, having it confirm a connection before ending would make sense. Though I would have to check against the local network as not all routers will have direct access to the net, i should think something can be done. Im going to have to add it to a growing list of updates and projects though so will add it when I next get time.

    Report
  • Comment Link Scott Frey Tuesday, 13 June 2017 19:04 posted by Scott Frey

    Feature request:
    Could this be modified to check not only for access points within range, but (or?) for internet connectivity? Perhaps by pinging 8.8.8.8

    Real world example use case:
    Twice now in setting these up for people, they have misspelled (technically mis-capitalized) the WPA password. so the Pi sees the network in range and correctly doesn't create a hot spot, but also doesn't join the network, so I have no access to it. (I'm currently using the other version of the script that does not test on a schedule)

    Report
  • Comment Link Graeme Monday, 12 June 2017 21:58 posted by Graeme

    Hi Patrick

    send you and email and a test autohotspot with more feedback.

    Report
  • Comment Link Patrick Saturday, 10 June 2017 20:19 posted by Patrick

    I have the space delimiters instead of the comma delimiters because in my script the comma do not allow for multiple ssids. as per your note on the setup without the switching. Saturday, 13 May 2017 09:57 posted by Graeme
    Hi Scott, it should work with multiple ssids. I know it has worked for others.
    just check each of the ssids are separated by spaces in the line ssids=('mySSID1' 'mySSID2')

    correcting all of my ' versus " issues, the script does connect to WiFi on boot if available, and generates a hotspot if it is not, now my issue is getting it to switch when Wifi is no longer available, or when it becomes available. I am not using cron right now, I am just running the script with sudo /usr/bin/autohotspot and it never switches between WiFi and hotspot I am going to try to send you my autohotspot script

    Report
  • Comment Link Graeme Friday, 09 June 2017 21:06 posted by Graeme

    Hi Patrick. It looks like a text conversion issue, the apostrophise are the wrong character in the first SED. Also the comma is missing in ORS',' command so multiple ssid won't get separated as that is being used as the delimiter in the line IFS=","
    I have done an image of my terminal nano screen to show the difference and how the script works
    http://www.raspberryconnect.com/images/awk.png

    Depending on the browser/text editor your using the formats can get converted. Especially if you do this in Windows. Just over type them in nano on the PI and it should work.

    If you are still having issues can you email me your autohotspot script and I will run it through my pi.

    My PI also shows the script with green | and blue SED, to date it works fine for me with two ssids in wpa_supplicant, of which one has spaces in the name.

    Just to clarify the quotes are as follows S = single D = double
    start to first |
    S D S
    Between first and second |
    S S S S S S
    Between 2nd and third |
    S D S S S
    After third |
    S S

    Report
  • Comment Link Patrick Friday, 09 June 2017 14:44 posted by Patrick

    I am not seeing any difference between the last two commands; ie the output from both sed commands is the same on my terminal.Your first sed combined the two single quotes into one double quote, but I typed it as we previously discussed. I expected to see MySSid1,MySSid2,MySSid3, but instead I saw
    ssid=MySSID1
    ssid=MySSid2
    ssid=MySSid3

    What I was saying about the wpassid=$(awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=' ' | sed 's/\"/’’/g' | sed 's/ $//') is that the coloration in my script tells me that something is wrong. after the initial awk everything is yellow until you get to a green | feeding into the second sed which is blue. That tells me the program is not handling the line correctly. That is why I am looking for typos and syntax errors. I even tried copy and paste from your script and it still is not correct

    Report
  • Comment Link Patrick Friday, 09 June 2017 13:03 posted by Patrick

    I am not seeing any difference between the last two commands; ie the output from both sed commands is the same on my terminal.Your first sed combined the two single quotes into one double quote, but I typed it as we previously discussed. I expected to see MySSid1,MySSid2,MySSid3, but instead I saw
    ssid=MySSID1
    ssid=MySSid2
    ssid=MySSid3

    Report
  • Comment Link Graeme Thursday, 08 June 2017 19:27 posted by Graeme

    Hi Patrick. The first " is part of a statement. It is looking for the entry ssid=" in the wpa_supplicant file. The other " in the first sed removes " from the end of the ssid. The last sed inserts a delimeter of ,. This then becomes one long string of all ssids. which is then split into mutiple ssids to check with the line ssids=($wpassid) so in your case it will pickup ssid="RPi" but not ssid=1

    if you paste it into terminal as
    sudo awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf
    then
    sudo awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=',' | sed 's/\"/''/g'
    then
    sudo awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=',' | sed 's/\"/''/g' | sed 's/,$//'

    you should see the breakdown of what it returns.

    Report
  • Comment Link Patrick Thursday, 08 June 2017 12:28 posted by Patrick

    wpassid=$(awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=' ' | sed 's/\"/’’/g' | sed 's/ $//')

    According to what I am seeing there are two places a double quote is used. After the first /ssid= and once in the first sed as you pointed out. This causes a mismatch in the quotation marks, and the first sed is then part of a statement instead of a command.

    If I plug that command line into python IDLE than it reads as I think it should, but in the terminal window, it reads different

    Report
  • Comment Link Graeme Wednesday, 07 June 2017 22:12 posted by Graeme

    Hi Patrick, if you notice the cause is due to the script with your setup rather than a typo, can you let me know your findings.
    Most of the wpassid line is clear except sed 's/\"/''/g' which is \double quote/ single quote single quote /g

    I wasn't aware of that way to get to hidden ssid. Maybe better than using the mac address scan. Have to try that one out. :)

    Report
  • Comment Link Patrick R Senn Wednesday, 07 June 2017 20:36 posted by Patrick R Senn

    I change the /usr/bin/autohotspot as you suggested and it confirmed the issue is in the wpassid line. I had already changed what I believed were typos that were mixing " and ''.
    Now I am not certain which quotes are correct where. I like using wpa_supplicant because I can just add 'scan_ssid=1' to my network information and it works with hidden networks.
    network={
    scan_ssid=1
    ssid="RPi"
    psk="abcd1234"
    }
    Now to find the typos.

    Report
  • Comment Link Graeme Wednesday, 07 June 2017 19:32 posted by Graeme

    Hi Patrick, try adding sudo to the cron command. I have added that into the guide now.
    Can you try just using the #ssids=('mySSID1' 'mySSID2' 'mySSID3') for your ssid and put a # in front of the 4 lines above. Just put a valid and then non valid ssid in autohotspot between cron cycles. See if it performs ok like that just to see if the issue is in the "wpassid=$(awk ...." line.

    Also is there any special characters or spaces in your SSID?


    The wlan messages you get "wlan0 Expired, wlan0 Configured 169.254.175.98/16" is correct. Wlan0 has been deactivated for Wifi so expired. The IP is effectively the router of the Hotspot that you have connected to, the the Pi is available on 10.0.0.5 through that router.

    Report
  • Comment Link Patrick R Senn Wednesday, 07 June 2017 16:54 posted by Patrick R Senn

    I also noticed when I have a hotspot it shows wlan0 Associated with RPiZeroW
    wlan0 Expired
    wlan0 Configured 169.254.175.98/16

    and I can puTTY in on 10.0.0.5 with my windows machine

    Report
  • Comment Link Patrick R Senn Wednesday, 07 June 2017 12:22 posted by Patrick R Senn

    My RPiZeroW connects to WiFi correctly upon bootup, but if there is no wifi, it does not create a hotspot. That being said, if I run sudo /usr/bin/autohotspot it will generate a hotspot. If I run sudo /usr/bin/autohotspot again it states "Hotspot already active" and disassociates my wlan0 from the RPi. If I run sudo /usr/bin/autohotspot a third time it states "Shutting hotspot down, Bringing WiFi Up." if I run sudo /usr/bin/autohotspot a fourth time it will generate a hotspot. It seems to me that it is not running through the autohotspot program correctly. Also. I just tried with WiFi available. It cycles through the three variants, {WiFi, HotSpot, Neither}, even if WiFi is available.

    Report
  • Comment Link Danny Sunday, 04 June 2017 21:26 posted by Danny

    Graeme! UPDATE! Progress, getting closer now to 100%! I did email you yesterday, but last night tried a couple new things and here's what we've got-

    After editing crontab as shown, the command not found errors are gone and now we're down to what's probably the final step of this- connectivity problems.

    # For more information ...
    #

    SHELL=/bin/sh
    PATH=/usr/local/sbin:usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

    # m h dom mon dow command
    */3 * * * * /usr/bin/autohotspot > /home/pi/cron.log 2>&1


    In network/interfaces, when wpa-conf is commented, home router connectivity is unreliable upon boot. It is uncommented per your suggestion to Susan on May 28, yielding quicker results in connecting to the home router at time of boot.

    Cold boot with home router available, after waiting for cron to execute autohotspot, cron.log indicates "Selected interface 'p2p-dev-wlan0'" and "Wifi already connected to network." Pings to the home router via root console result "connect: Network is unreachable". dnsmasq and hostapd are stopped. Manually running autohotspot echoes same two lines as is in cron.log.

    While still booted, when power is removed from home router and after waiting for cron to run autohotspot, the Pi3 successfully starts the hotspot (this is a substantial improvement). It issues an ip within the range specified, is open to ssh and seems to work fine, dnsmasq and hostapd are running. cron.log reads "Cleaninf wifi files and Activating hotspot", "Selected interface 'p2p-dev-wlan0'" and "OK". Manually running autohotspot echoes "Hotspot already active"

    While still booted, yet, when power is applied to the home router and after waiting for cron to run autohotspot, the Pi3 successfully stops the hotspot. cron.log reads "Hotspot already active" even though it is no longer transmitting. Suspecting this anomaly to be due to two factors -- the router's boot time and the cron timer cycle -- I waited longer, and after manually running autohotspot it echoed:
    Active: active (running) since ..
    Shutting Down Hotspot
    Hotspot Deactivated, Bringing Wifi Up
    Failed to connect to non-global ctrl_ifname: (nil) error: No such file or directory
    Wifi failed to connect, Creating Hotspot again
    Failed to connect to non-global ctrl_ifname: (nil) error: No such file or directory

    But the hotspot was not active, wlan0 not connected to anything either, indicated by no hotspot and failed pings to the home router via root console.


    At this point it seems the Pi hung, because when power is again removed from the home router (Pi has remained booted), after a 10-minute wait the hotspot is not automatically started. Manually running autohotspot echoes:
    command failed: Device or resource busy (-16)
    Failed to connect to non-global ctrl_ifname: (nil) error: No such file or directory
    RTNETLINK answers: File exists

    Rebooting the Pi, while home router remains unavailable, results in a fully-functional hotspot.

    While the Pi remains booted with working hotspot and power is re-applied to the home router, the hotspot is stopped and cron.log reads "command failed: Invalid exchange (-52)" and "Hotspot already active". Manually running autohotspot echoes:
    Active: active (running) since ..
    Shutting Down Hotspot
    Hotspot Deactivated, Bringing Wifi Up
    Wifi connection ok
    Wifi connection established...

    Yet I cannot ping the home router or google via root console, nor is ssh available.

    Having said all this, the environment and/or permissions seem to have been resolved by the edit to crontab. Maybe there's a more appropriate way to have fixed it?

    Additionally, and the current problem: no network connection while connected to the home router, and connection(s) to the home router seem to cause problems for the script. How can we fix that? Once fixed, for improving upon your script, I recommend modifying autohotspot to do this:

    - Known SSID available?
    - Wait 60 seconds # this will give time for the router to reboot or for the Pi to be carried out of fringe reception and closer to the router, as would be in the case of coming home with it
    - Verify known SSID remains available
    - Kill hotspot
    - Connect to home router
    - Wait 10 seconds #maybe a little longer?
    - Determine gateway (router) ip
    - Ping the router
    - Success? Ok. No success? Loop once or fallback to hotspot for x minutes before retrying,

    Report
  • Comment Link Graeme Saturday, 03 June 2017 22:30 posted by Graeme

    Hi Danny. The RTNETLINK answers: File exists error means that the network wifi files are still in place. The script has to clear them before the hotspot can be started. If it will be permissions again if that can't be cleared. If your already connected to the network then that response is fine.
    the error "Failed to connect to non-global ctrl_ifname: (nil) error:no such file or directory"
    is again clearing a file but it is not always there so often not found but done as a just in case.

    The fact that it works at boot means it works, you have some non standard permissions issues with the sudo use or with the cron user.

    I don't think you need to add more to the script as it handles bringing the necessary network files up and down. Once i get a new sd I will check it on a clean new image in case of recent changes but it seems there is something in your setup.


    Can you e-mail me your autohotspot file please so i can test it on my pi.

    Report
  • Comment Link Danny Saturday, 03 June 2017 22:13 posted by Danny

    Maybe some of the information at https://unix.stackexchange.com/questions/113939/wpa-supplicant-overriding-iwconfig can point us in the right direction?

    Someone on there posted-

    I fixed this by adding nohook wpa_supplicant to my dhcpcd config file, and changing my "connect" script to only invoke wpa-supplicant for wpa networks.

    sudo iwconfig "$INTERFACE" essid "$SSID" key "$PSK" 2>/dev/null
    WPA=$(printf "$TABLE" | grep "$SSID" | cut -s -d $'\t' -f 2- | grep "WPA")
    if [[ $WPA ]]; then
    sudo wpa_supplicant -B -D wext -i "$INTERFACE" -c "$WPA_SUPPLICANT_CONFIGURATION_FILE"`
    fi
    sudo dhcpcd "$INTERFACE"

    Report
  • Comment Link Danny Saturday, 03 June 2017 21:42 posted by Danny

    Hi Graeme, stil no luck, having tried editing autohotspot to reflect /sbin/iw (also tried sudo /sbin/iw). Same symptoms, where cron.log keeps throwing “/usr/bin/autohotspot: line 40: iw: command not found" no matter what. When I manually execute autohotspot in terminal I get:
    Failed to connect to non-global ctrl_ifname: (nil) error:no such file or directory
    RTNETLINK answers: File exists

    Trying everything, here! What do you think?

    Report
  • Comment Link Graeme Saturday, 03 June 2017 11:19 posted by Graeme

    Hi Danny. Thanks again for the detail.
    I will be getting a new SD card on Monday so will try a fresh install, as all my up to date Rpi's are running fine. Just to check there no significant changes.

    Thanks for pointing out the apostrophe issue, my text edit sneaked that one in.
    Also the dnsmasq bug. It's not been an issue for me even though using the bugged version but obviously can have an affect. That will also break the other autohotspot script, as yet nobody has reported the issue.

    My user path includes sbin /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
    and sudo's PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    it also works in autohotspot if I enter /sbin/iw ... could also try sudo /sbin/iw ....

    I haven’t consciously added it so don't know why it is not in your path. but it should work with /sbin/iw.

    if you stop the cron job and run the sudo /usr/bin/autohotspot from a terminal does it work ok when you swith the router on and off?

    Report
  • Comment Link Danny Saturday, 03 June 2017 07:51 posted by Danny

    Thanks for helping along! We’re making great progress, though the problem is not resolved — we’re close, and at this point I’m pretty sure all we’re looking at is iw not executing properly from the script due to, maybe, a path issue. Root’s $PATH is /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin. Other sudoer user’s $PATH is /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games.

    1. Your script posted on your site at /images/autohotspot-switch.txt contains an error. Specifically, at the end of line 8 your portion of code containing sed ‘s/,$//’) contains apostrophes that, when copy/pasted, don’t translate properly into terminal. I recommend editing your script with plain-text apostrophes there. I have corrected that on my end in the Pi3.

    2. The reason dnsmasq was failing to start, resulting in “junk found” is due to Debian big #860064 where, when dns-root-data is installed dnsmasq will fail to start. I recommend adding to your overall instructions (for Debian users) to execute apt-get purge dns-root-data following the apt-get update. I have purged dns-root-data on my end, and dnsmasq no longer fails to start. No errors result in status dnsmasq nor hostapd.

    3. I altered my DHCP range stated in dnsmasq.conf to 10.0.0.2,10.0.0.50 per your recommendation so that the wlan0 ip stated in autohotspot is included in the DHCP range. No improvement in operation can be determined yet because the overall problem is not yet resolved.

    4. Our temporary cron.log throws “/usr/bin/autohotspot: line 40: iw: command not found” in each scenario of (a) booting with home router available and (b) booting with no home router available. I attempted to overcome the problem by editing autohotspot for “/sbin/iw” but that did not solve the problem, so I reverted to your verbatim script. iw is installed and runs fine when commanded in terminal — just not via the script. No other errors are shown in cron.log. However, cron.log does indicate “Hotspot already active” regardless of whether the hotspot is actually active or not- I attribute this to the failure in executing iw to make the swap.

    5. Because iw is not executing through the script, I had to uncomment wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf in network/interfaces in order to get the Pi3 to operate properly with the home router. I suspect that once we correct the iw execution via the autohotspot script I’ll be able to re-comment wpa-conf.

    6. When cold-booting with home router available, the Pi3 connects to the home router, obtains an ip, and ssh is accessible. Same, fully working, in the opposite when cold-booting with no home router available, the Pi3 starts the hotspot, gives itself an ip within the range specified in dnsmasq.conf, and ssh is accessible.

    8. While booted with active hotspot and the home router is restored the cron task successfully identifies the home router, connects to it, and shuts down the hotspot. ssh is accessible.

    9. THE PROBLEM SUMMARY. When already booted with home router available (connected) and the home router is lost, the hotspot does not start regardless of length of time waited. At this time, cron.log only indicates “/usr/bin/autohotspot: line 40: iw: command not found” and “Hotspot already active” — nothing more. From this problem condition, when the home router is restored, the autohotspot script does indeed catch the home router and connect to it, restoring ssh access etc.

    Report
  • Comment Link Graeme Friday, 02 June 2017 21:12 posted by Graeme

    Hi Danny. Thanks for the detailed response.
    There are two things that stand out,
    dnsmasq is the issue as it is not starting. In your dnsmasq.conf file the ip range has been changed to dhcp-range=10.0.0.200,10.0.0.250,12h
    but the autohotspot ip is 10.0.0.2. It needs to be within the range set in the dnsmasq file. so try changing autohotspot to 10.0.0.205

    Also you are getting a sed error,sed: -e expression #1, char 1: unknown command: `?, though it's not effecting your router being detected it is not right.
    the line starting with wpassid near the top will be the issue. Just check it is complete, best to use the download link just before the script.

    I did add a few extra lines last night so it would handle ssids with spaces, the IFS bits. It's working fine for me without errors.

    Let me know how you get on, if that is no use then I will go through your logs again. You are welcome to email me if you need to add log files. admin@ this site.

    Report
  • Comment Link Danny Friday, 02 June 2017 07:09 posted by Danny

    First, I just want to say that I really appreciate your help. I love the utility of your work and I believe with what you’ve done and others’ contributions it’s going to evolve wonderfully. Thank you.

    Onward, here’s detail of the configuration and the behavior. I’m suspicious of my network/interfaces config and hope to get your approval or correction. Two scenarios are presented; the second scenario is detailed in four phases. The network itself is probably inconsequential to troubleshooting but, in case it is: Home router is at 10.0.0.1 with DHCP range 10.0.0.100 to 10.0.0.150; Pi3 gets DHCP reservation 10.0.0.2 in home router based on Pi3 wlan0 mac address; Pi3 (testbox) is at 10.0.0.2 per autohotspot script with DHCP range 10.0.0.200 to 10.0.0.250 per dnsmasq.conf. The overall problem is that the hotspot is failing.


    SCENARIO 1:

    INITIAL CONDITION: HOME ROUTER AVAILABLE UPON BOOT (NOT EXPECTING THE HOTSPOT)

    - hotspot is off (ok)
    - wlan0 IP is correct, 10.0.0.2, as specified in autohotspot (ok)
    - able to ping the home router at 10.0.0.1 (ok)
    - able to ping google.com:80 (ok)
    - able to establish ssh connection from other local network clients (ok)

    cron log:
    sed: -e expression #1, char 1: unknown command: `?'
    Hostspot already active

    systemctl status hostapd:
    hostapd.service - LSB: Advanced IEEE 802.11 management daemon
    Loaded: loaded (/etc/init.d/hostapd; generated; vendor preset: disabled)
    Active: active (running) since Thu 2017-06-01 21:49:34 PDT; 1min 0s ago
    Docs: man:systemd-sysv-generator(8)
    Process: 517 ExecStart=/etc/init.d/hostapd start (code=exited, status=0/SUCCESS)
    Tasks: 1 (limit: 4915)
    CGroup: /system.slice/hostapd.service
    └─526 /usr/sbin/hostapd -B -P /run/hostapd.pid /etc/hostapd/hostapd.conf

    qas 01 21:49:33 testbox systemd[1]: Starting LSB: Advanced IEEE 802.11 management daemon...
    qas 01 21:49:34 testbox hostapd[517]: Starting advanced IEEE 802.11 management: hostapd.
    qas 01 21:49:34 testbox systemd[1]: Started LSB: Advanced IEEE 802.11 management daemon.

    systemctl status dnsmasq:
    dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
    Loaded: loaded (/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
    Active: failed (Result: exit-code) since Thu 2017-06-01 21:49:33 PDT; 1min 46s ago
    Process: 494 ExecStart=/etc/init.d/dnsmasq systemd-exec (code=exited, status=1/FAILURE)
    Process: 480 ExecStartPre=/usr/sbin/dnsmasq --test (code=exited, status=0/SUCCESS)

    qas 01 21:49:33 testbox systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
    qas 01 21:49:33 testbox dnsmasq[480]: dnsmasq: syntax check OK.
    qas 01 21:49:33 testbox dnsmasq[494]: dnsmasq: junk found in command line
    qas 01 21:49:33 testbox dnsmasq[494]: junk found in command line
    qas 01 21:49:33 testbox systemd[1]: dnsmasq.service: Control process exited, code=exited status=1
    qas 01 21:49:33 testbox systemd[1]: Failed to start dnsmasq - A lightweight DHCP and caching DNS server.
    qas 01 21:49:33 testbox systemd[1]: dnsmasq.service: Unit entered failed state.
    qas 01 21:49:33 testbox systemd[1]: dnsmasq.service: Failed with result 'exit-code'.


    SCENARIO 2:

    INITIAL CONDITION: NO HOME ROUTER AVAILABLE UPON BOOT (EXPECTING THE HOTSPOT)

    - hotspot is on, broadcasting ssid and connectable, but not issuing IP (problem)
    - wlan0 IP is correct, 10.0.0.2, as specified in autohotspot (ok)
    - all pings unreachable (except while pinging 10.0.0.2) (problem)

    cron log:
    sed: -e expression #1, char 1: unknown command: `?'
    /usr/bin/autohotspot: line 74: wpa_cli: command not found
    RTNETLINK answers: File exists
    Job for dnsmasq.service failed because the control process exited with error code.
    See "systemctl status dnsmasq.service" and "journalctl -xe" for details.

    cron log several minutes after boot:
    sed: -e expression #1, char 1: unknown command: `?'
    Hostspot already active

    systemctl status hostapd:
    hostapd.service - LSB: Advanced IEEE 802.11 management daemon
    Loaded: loaded (/etc/init.d/hostapd; generated; vendor preset: disabled)
    Active: active (running) since Thu 2017-06-01 21:58:57 PDT; 54s ago
    Docs: man:systemd-sysv-generator(8)
    Process: 528 ExecStart=/etc/init.d/hostapd start (code=exited, status=0/SUCCESS)
    Tasks: 1 (limit: 4915)
    CGroup: /system.slice/hostapd.service
    └─539 /usr/sbin/hostapd -B -P /run/hostapd.pid /etc/hostapd/hostapd.conf

    qas 01 21:58:56 testbox systemd[1]: Starting LSB: Advanced IEEE 802.11 management daemon...
    qas 01 21:58:57 testbox hostapd[528]: Starting advanced IEEE 802.11 management: hostapd.
    qas 01 21:58:57 testbox systemd[1]: Started LSB: Advanced IEEE 802.11 management daemon.

    systemctl status dnsmasq:
    dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
    Loaded: loaded (/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
    Active: failed (Result: exit-code) since Thu 2017-06-01 21:58:56 PDT; 1min 45s ago
    Process: 501 ExecStart=/etc/init.d/dnsmasq systemd-exec (code=exited, status=1/FAILURE)
    Process: 494 ExecStartPre=/usr/sbin/dnsmasq --test (code=exited, status=0/SUCCESS)

    qas 01 21:58:56 testbox systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
    qas 01 21:58:56 testbox dnsmasq[494]: dnsmasq: syntax check OK.
    qas 01 21:58:56 testbox dnsmasq[501]: dnsmasq: junk found in command line
    qas 01 21:58:56 testbox systemd[1]: dnsmasq.service: Control process exited, code=exited status=1
    qas 01 21:58:56 testbox systemd[1]: Failed to start dnsmasq - A lightweight DHCP and caching DNS server.
    qas 01 21:58:56 testbox systemd[1]: dnsmasq.service: Unit entered failed state.
    qas 01 21:58:56 testbox systemd[1]: dnsmasq.service: Failed with result 'exit-code'.


    PHASE TWO: HOME ROUTER POWERED-UP WHILE PI REMAINS BOOTED AND HOTSPOT ON (EXPECTING THE HOTSPOT OFF AND SWITCH TO HOME ROUTER AFTER >2 MINS PER CRON)

    - all behavior is same as cold-boot while home router is available (ok)

    PHASE THREE: HOME ROUTER IS POWERED-DOWN WHILE PI REMAINS BOOTED AND HOTSPOT OFF (EXPECTING THE HOTSPOT ON AND SWITCH TO HOTSPOT AFTER >2 MINS PER CRON)

    - hotspot is off and not broadcasting ssid (problem)

    systemctl status hostapd:
    hostapd.service - LSB: Advanced IEEE 802.11 management daemon
    Loaded: loaded (/etc/init.d/hostapd; generated; vendor preset: disabled)
    Active: active (running) since Thu 2017-06-01 21:58:57 PDT; 25min ago
    Docs: man:systemd-sysv-generator(8)
    Process: 528 ExecStart=/etc/init.d/hostapd start (code=exited, status=0/SUCCESS)
    Tasks: 1 (limit: 4915)
    CGroup: /system.slice/hostapd.service
    └─539 /usr/sbin/hostapd -B -P /run/hostapd.pid /etc/hostapd/hostapd.conf

    qas 01 21:58:56 testbox systemd[1]: Starting LSB: Advanced IEEE 802.11 management daemon...
    qas 01 21:58:57 testbox hostapd[528]: Starting advanced IEEE 802.11 management: hostapd.
    qas 01 21:58:57 testbox systemd[1]: Started LSB: Advanced IEEE 802.11 management daemon.
    qas 01 22:00:08 testbox hostapd[539]: wlan0: STA (::mac::) IEEE 802.11: associated
    qas 01 22:00:08 testbox hostapd[539]: wlan0: STA (::mac::) RADIUS: starting accounting session 5930F090-
    qas 01 22:00:08 testbox hostapd[539]: wlan0: STA (::mac::) WPA: pairwise key handshake completed (RSN)
    qas 01 22:08:14 testbox hostapd[539]: wlan0: STA (::mac::) IEEE 802.11: disassociated
    qas 01 22:08:14 testbox hostapd[539]: wlan0: STA 00:00:00:00:00:00 IEEE 802.11: disassociated

    systemctl status dnsmasq:
    dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
    Loaded: loaded (/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
    Active: failed (Result: exit-code) since Thu 2017-06-01 21:58:56 PDT; 27min ago
    Process: 501 ExecStart=/etc/init.d/dnsmasq systemd-exec (code=exited, status=1/FAILURE)
    Process: 494 ExecStartPre=/usr/sbin/dnsmasq --test (code=exited, status=0/SUCCESS)

    qas 01 21:58:56 testbox systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
    qas 01 21:58:56 testbox dnsmasq[494]: dnsmasq: syntax check OK.
    qas 01 21:58:56 testbox dnsmasq[501]: dnsmasq: junk found in command line
    qas 01 21:58:56 testbox systemd[1]: dnsmasq.service: Control process exited, code=exited status=1
    qas 01 21:58:56 testbox systemd[1]: Failed to start dnsmasq - A lightweight DHCP and caching DNS server.
    qas 01 21:58:56 testbox systemd[1]: dnsmasq.service: Unit entered failed state.
    qas 01 21:58:56 testbox systemd[1]: dnsmasq.service: Failed with result 'exit-code'.


    PHASE FOUR: HOME ROUTER IS POWERED-UP WHILE PI REMAINS BOOTED AND HOTSPOT FAILED TO START (EXPECTING THE HOTSPOT TO REMAIN OFF AND SWITCH TO HOME ROUTER AFTER >2 MINS PER CRON)

    - all behavior is same as cold-boot while home router is available (ok)


    ALL CONFIGURATION FILES EXCEPT THE AUTOHOTSPOT SCRIPT. ONLY CHANGE TO AUTHOTSPOT SCRIPT IS THE IP AS p a add 10.0.0.2/24 dev wlan0. USING WPASSID=, LEFT SSID= COMMENTED


    /etc/network/interfaces:
    # auto lo
    # iface lo inet loopback

    auto eth0
    iface eth0 inet dhcp

    auto lo wlan0
    iface lo inet loopback

    allow-hotplug wlan0
    iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf


    /etc/hostapd/hostapd.conf:
    interface=wlan0
    driver=nl80211
    ssid=(masked)
    hw_mode=g
    channel=6
    wmm_enabled=0
    macaddr_acl=0
    auth_algs=1
    ignore_broadcast_ssid=0
    wpa=2
    wpa_passphrase=(masked)
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=TKIP
    rsn_pairwise=CCMP


    added to end of /etc/dnsmasq.conf:
    #Pi3Hotspot Config
    #stop DNSmasq from using resolv.conf
    no-resolv
    #Interface to use
    interface=wlan0
    bind-interfaces
    dhcp-range=10.0.0.200,10.0.0.250,12h


    /etc/wpa_supplicant/wpa_supplicant.conf:
    network={
    ssid=“(masked)”
    psk=“(masked)”
    key_mgmt=WPA-PSK
    }


    /etc/systemd/system/autohotspot.service:
    [Unit]
    Description=Generates a non-internet Hotspot for ssh when a listed ssid is not in range
    After=network-online.target
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/bin/autohotspot
    [Install]
    WantedBy=multi-user.target


    crontab: (sudo in cron had no effect on performance and was therefore not used in the information presented)
    */2 * * * * /usr/bin/autohotspot > /home/pi/cron.log 2>&1

    Report
  • Comment Link Danny Thursday, 01 June 2017 23:42 posted by Danny

    Hi, Grame, I'm going do to what you recommended but to rule out any weird anomalies from last night's messing with it I'm doing a completely fresh install. I have a suspicion that my network/interfaces weren't configured right (due to weird ip/no ip behavior when connecting). Would you mind sharing a complete interfaces example instead of modified lines? I might have butchered lo.

    Thank you so very much for all of your help!!

    Report
  • Comment Link Graeme Thursday, 01 June 2017 20:34 posted by Graeme

    Hi Danny, we need to check that the script is working ok, though as it works at boot that suggests it is. You're need to do this with a screen.
    run the script manually with sudo /usr/bin/autohotspot it will tell you what it's doing. Try with the router on and off. If that is ok then the script is setup ok.
    As running it manually and in a cron is not the same thing, next check the cron is working. Using; sudo systemctl status cron you will see in the times of the results that it runs every 2 minutes. It should report any issues.
    The other thing is you can get the cron to output to a log file which will show what the autohotspot script outputted on each run.
    In the cron, after autohotspot add: > /home/pi/cron.log 2>&1
    The file will just contain the last output from autohotspot the last time the cron run.
    Hopefully this will give you a clue to if the cron is working or if there is an issue with the autohotspot script.

    Let me know what results you get and we can look into it further.

    Report
  • Comment Link Danny Thursday, 01 June 2017 03:18 posted by Danny

    Graeme, I really appreciate your quick response! Tried your recommendation of adding sudo in crontab, but that didn't solve the problem. Maybe there's a second thing I could try, in order to get it fully working and fix that problem?

    Report
  • Comment Link Graeme Wednesday, 31 May 2017 20:45 posted by Graeme

    Hi Danny, Im glad the script is of some use to you. It sounds like you are having permissions issues. Try adding sudo to your crontab command
    */2 * * * * sudo /usr/bin/autohotspot

    as it only seems to be when the AP is started.
    The service will start AP mode at first boot so permissions not an issue but it is when the cron does its thing it is failing for you.

    Let me know if that fixes it for you and I will add it to the guide.

    Report
  • Comment Link Danny Wednesday, 31 May 2017 06:34 posted by Danny

    Graeme, this is fantastic work! Thank you! Also, Tino, Susan and everyone else, thank you for your improvements and questions that led to getting my box working.

    I'm having a problem that I can't figure out how to solve, and I'm hoping for help-

    Scenario 1: When my Pi3 cold boots without the home router available, it starts the access point. While booted, when the home router is gained the script connects to the home router and disables the access point. When the home router is subsequently lost, the Pi3 does not start the access point.

    Scenario 2: When cold booted with wifi available, it connects to the home router and does not start the access point. While booted, when wifi is lost the it does not start the access point.

    Overall problem: The access point does not start upon losing connection to the home router, regardless of the wait (cron set to 2 minutes, but wait attempted significantly longer). The only time the access point starts is upon a cold boot when the home router is not available.

    Would you please help advise a solution?

    Report
  • Comment Link Graeme Sunday, 28 May 2017 09:34 posted by Graeme

    Hi susan, sorry for slow response, i have been away. The service triggers once the system signals the network is available so it should connect but it may be possible that another program causes a long enough delay for the ssid not to be detectable. Try removing the # infront of the wpa_supplicant line in /etc/network/interfaces it isn't needed for this script. The pi will connect to wifi, if available, without the script. Then the script will asses the situation and switch if required. Let me know if you still have an issue.

    Report
  • Comment Link Susan Thursday, 25 May 2017 22:47 posted by Susan

    Some of the time, on bootup, the service will fail to detect the local wifi and it will start the hotspot. Once the cronjob triggers, it realizes there is a local wifi and will make the switch. Is it possible the service is starting before the network is ready or able to detect the local wifi?

    Report
  • Comment Link Graeme Tuesday, 02 May 2017 21:57 posted by Graeme

    Hi Tino, Thanks for the update. I won't be able to try this one out as I don't have hidden networks or email configured but I will be adding it to the article as an alternative script. Thanks for sharing this.

    Report
  • Comment Link Tino Tuesday, 02 May 2017 21:07 posted by Tino

    Hi Graeme, here is another update. I have some hidden networks in my configuration, so I also wanted to scan for some mac addresses. In addition, I want to have an e-mail with the current IP address if connection was established to a wifi network or personal hotspot of my phone or tablet.

    Please see the modified script below, Cheers.

    #!/bin/bash
    ##
    # Wifi config - if no prefered Wifi generate a hotspot
    ##

    ## enter required ssids: ssids=('ssid1' 'ssid2') ...

    #ssids=('mySSID1' 'mySSID2')

    ## ... or let the script parse your wpa_supplicant.conf

    ssids=$(awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=' ' | sed 's/\"/''/g' | sed 's/ $//')

    ## for hidden wifi networks, add mac adresses here:

    macAdresses=('11:22:33:44:55:66' '66:55:44:33:22:11')

    ## build network string
    networks=($ssids ${macAdresses[@]})

    createAdHocNetwork()
    {
    ip link set dev wlan0 down
    ip a add 10.0.0.5/24 dev wlan0
    ip link set dev wlan0 up
    systemctl start dnsmasq
    systemctl start hostapd
    }
    KillHotspot()
    {
    echo "Shutting Down Hotspot"
    ip link set dev wlan0 down
    systemctl stop hostapd
    systemctl stop dnsmasq
    ip addr flush dev wlan0
    ip link set dev wlan0 up
    }
    #check for entry in range
    ssidChk=('NoSSid')
    for entry in "${networks[@]}"
    do
    if iw dev wlan0 scan ap-force | grep "$entry" > /dev/null ;then
    ssidChk=$entry
    break
    else
    ssidChk='NoSSid'
    fi
    done

    if [ $ssidChk != "NoSSid" ]
    then
    if systemctl status hostapd | grep "(running)"
    then #hotspot running and network entry in range
    KillHotspot
    echo "Hotspot Deactivated, Bringing Wifi Up"
    wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf > /dev/null 2>&1
    # wait and check if wifi connection was established
    sleep 10
    if wpa_cli status | grep 'wlan0' > /dev/null
    then
    echo "Wifi connection ok"
    # send e-mail with ip address
    echo "Wifi connection established..." |mail -s "[WifiConnect] $(hostname) - IP: $(hostname -I|cut -d" " -f1) / `date +\%Y.\%m.\%d` - `date +\%H:\%M` "
    else
    echo "Wifi failed to connect, Creating Hotspot again"
    wpa_cli terminate
    createAdHocNetwork
    fi
    elif wpa_cli status | grep 'wlan0'
    then #If already connected stop script
    echo "Wifi already connected to network"
    else #network entry exists and no hotspot running connect to wifi network
    echo "Connecting to WiFi Network"
    wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf > /dev/null 2>&1
    if wpa_cli status | grep 'wlan0' > /dev/null
    then
    echo "Wifi connection ok"
    # send e-mail with ip address
    echo "Wifi connection established..." |mail -s "[WifiConnect] $(hostname) - IP: $(hostname -I|cut -d" " -f1) / `date +\%Y.\%m.\%d` - `date +\%H:\%M` "
    else
    echo "Wifi failed to connect, Creating Hotspot instead"
    wpa_cli terminate
    createAdHocNetwork
    fi
    fi
    else #no network entry in range
    if systemctl status hostapd | grep "(running)" > /dev/null
    then
    echo "Hostspot already active"
    elif wpa_cli status | grep 'wlan0' > /dev/null
    then
    echo "Cleaning wifi files and Activating Hotspot"
    wpa_cli terminate
    ip addr flush wlan0
    ip link set dev wlan0 down
    rm -r /var/run/wpa_supplicant > /dev/null
    createAdHocNetwork
    else #"No network entry in range, activating Hotspot"
    createAdHocNetwork
    fi
    fi

    Report
  • Comment Link Graeme Sunday, 30 April 2017 10:58 posted by Graeme

    Hi Tino, thanks for reposting the command. I will update my RPi's and add to the article in due course. Very helpful, Thanks.

    Report
  • Comment Link Tino Saturday, 29 April 2017 13:45 posted by Tino

    Hi Graeme, as mentioned before, reading the ssids directly from wpa_supplicant.conf would help to ensure that the script looks only for known networks/ssids.

    Thats why I have changed line 6:
    #ssids=('mySSID1' 'mySSID2' 'mySSID3')
    ssids=$(awk '/ssid="/{ print $0 }' /etc/wpa_supplicant/wpa_supplicant.conf | awk -F'ssid=' '{ print $2 }' ORS=' ' | sed 's/\"/''/g' | sed 's/ $//')

    Cheers,
    Tino

    Report
  • Comment Link Graeme Friday, 28 April 2017 21:48 posted by Graeme

    Hi Tino, thanks for pointing that out. It worked in testing so I must cleared it in the code clean up before posting as I did only use the 3rd slot for the final checks. Good point about using the wpa file for both scripts which would make them set-up and forget scripts.

    Report
  • Comment Link Tino Friday, 28 April 2017 14:43 posted by Tino

    Hi,

    thank you for this helpful update of your script!

    But short note about the loop:

    If you use multiple ssids ('mySSID1' 'mySSID2' 'mySSID3') then the result of your loop will end with ssidChk='NoSSid' even if mySSID1 or mySSID2 are in range but mySSID3 is not.

    So I think you have to insert a break into the loop right after "ssidChk=$ssid".

    Furthermore, you could parse your wpa_supplicant.conf and scan for the ssid= entries and write the results to the $ssids variable. Just an idea ...

    Cheers,
    Tino

    Report

Additional information