I have a Raspberry Pi 3B running Raspbian Lite Stretch (2018-03-13).

I have an IoT device that broadcasts an AP. I want my RPi to join this AP whenever it is available (i.e., the IoT device is on). But when the AP is not available, I want it to fall back to connecting to my home infrastructure network.

I've configured the networks in the wpa_supplicant config, and assigned a priority of 1000 to the IoT network; if I turn the Raspberry Pi on while the IoT network is broadcasting, it correctly connects to it. When the IoT device goes off, the Raspberry Pi switches to the home network.

However, when the IoT device turns on after the RPi, the RPi does not automatically leave the home network and associate to the IoT device's network.

I'm OK with having to kick off the switch through a cron job or on some other trigger.

Doesn't work: wpa_cli select_network

The first technique I've tried is simply using wpa_cli select_network to switch manually. After running it, list_networks output changes to have this [DISABLED]/[CURRENT] indicator. However, it does not actually change networks.

Selected interface 'p2p-dev-wlan0'
network id / ssid / bssid / flags
0   HomeNetwork any [DISABLED]
1   IoTDevice   any [CURRENT]

I've also tried using wpa_cli reconnect and wpa_cli reassociate but these don't do anything. wpa_cli disconnect also does nothing, and wpa_cli disassociate [BSSID] just reports failure.

Doesn't work: iwconfig

$ sudo iwconfig wlan0 essid "IoTDevice"
Error for wireless request "Set ESSID" (8B1A) :
    SET failed on device wlan0 ; Operation already in progress.

Doesn't work: iw

$ sudo iw wlan0 connect IoTDevice
command failed: Operation already in progress (-114)

Not supported anymore, presumably: wpa-roam

Many guides suggest putting the device into wpa-roam mode, but the information on how to do so is out of date; all the guides reference /etc/network/interfaces, which seems to be virtually blank since the switch to dhcpcd.

Does work, but sucks: Nuking dhcpcd

Other people also express frustration with difficulty restarting wpa_supplicant short of blowing away dhcpcd each time. But when I do this, it does switch to the higher priority network if available.

I've written an answer that periodically scans for the desired network and kills dhcpcd when it's found; this works, but it is a very heavy-handed solution.

Since I can change networks just fine when the associated AP goes down without killing any processes, I shouldn't need to do this.


I'm trying to avoid cargo cult answers that involve flipping interfaces on and off, killing processes and anointing the board with sacred oils. How is switching networks really supposed to work?

  • If you want any helpful answers I suggest you provide some information, starting with which OS, what you actually tried, and avoid emotive phrases like " blowing away dhcpcd" and say what commend this may refer to. – Milliways Mar 28 at 7:17
  • The OS, Raspbian Lite 4.9, is in the first sentence. The linked answer about dhcpcd includes the commands to kill dhcpcd but I have also added it to my post. – rgov Mar 28 at 7:24
  • Post OS in a tag - don't expect people to follow links, and guess what you did. There is No such thing as "Raspbian Lite 4.9" – Milliways Mar 28 at 7:28

If you simply call wpa_cli without specifying the Interface, by default your raspbian stretch uses the interface 'p2p-dev-wlan0', as I can see in the output you posted.

Try the manual switching with wpa_cli by specifying the Interface (assuming that wlan0 is your regular wireless Interface, you want to use to connect to the Access point):

wpa_cli -i wlan0 select_network

I'm not happy with this solution, but it does work.

This script will scan for the desired network, and if it is found, it will restart dhcpcd. This disconnects from the current network and then connects to the highest priority network (as configured in wpa_supplicant.conf).

#!/bin/sh
if iwlist wlan0 scan | grep -q "$1"; then
  logger Network "$1" is available, switching
  systemctl restart dhcpcd
fi

Note that iwlist lies about scanning if it is not invoked as root; it will just spit out the details for the current network. Because Linux networking isn't full of enough pitfalls, I guess.

We can save this file in /usr/bin/switch-network-if-available.sh and then set up a cronjob to execute it every minute:

* * * * * root /usr/bin/switch-network-if-available.sh IoTDevice
  • Seems the main problem is to switch a wifi connection on the same interface wlan0. Is it an option to have separate interfaces wlan0 and wlan1 for each wifi and let bonding do its work with fail over? Then you can specify what interface should be used when available. – Ingo Mar 28 at 10:36

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.