For a device aimed at least partly at getting kids into programming, setting up access to my hidden WiFi network on a Raspberry Pi proved a little more challenging than I expected.
As a man who grew up in the eighties and who’s first tentative steps into programming were on the school’s BBC Micro and on my first home computer, an Acorn Electron, picking up my first Raspberry Pi brought with it a few flashbacks to those heady (aka geeky) days of my youth. Here are a bunch of guys who grew up at the same time that I did, who learnt about computers in the same way that I did and who are trying to give kids today a taste of the same experience we had. Here’s a simple computer you can pick up for twenty quid or so that you actually make do stuff yourself, rather than simply pointing and clicking at icons downloaded from the Internet or slapping in a Blu-ray you bought at the local game store.
I got a less pleasant flashback when I tried to configure my USB WiFi dongle to connect to my home network; rather like the first time I tried to type a program into my Acorn Electron and was bewildered as to why I couldn’t enter more than six lines (’til I realised you had to press the enter key after each one).
How did I ever end up making a living out of this stuff?
Pi-Fi
My needs were simple if a little unconventional. Without a spare keyboard or monitor, and not wishing to repurpose my TV, I wanted to set my Pi up on my wireless network with DHCP assigned settings so that I could just remote into it to do stuff. Most of my Linux experience has been on Red Hat and its derivatives so the Raspbian operating system, based as it is on Debian, might take a bit of adjusting to, but other than that it should be plain sailing.
And it probably would have been if it hadn’t been for my home WiFi network being “hidden” (it doesn’t broadcast its SSID).
But I did learn a few things along the way.
Pi-Fried
My beautifully tiny WiFi dongle came from The Pi Hut and needs no drivers or other guff installing to work with Raspbian. Having got my Pi on my network using a network cable to start with I was able to ssh into it with the usual pi/raspberry user name and password and then follow the simple instructions on The Pi Hut web site to configure it. This was merely a matter of opening /etc/wpa_supplicant/wpa_supplicant.conf and adding my network details to it:-
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="devsumo" psk="MyPassPhrase" }
Rebooting with my dongle attached showed me a wlan0 looking healthy in every respect save for having no IP address and therefore being of the slightest use:-
pi@raspberrypi ~ $ ifconfig wlan0 wlan0 Link encap:Ethernet HWaddr 00:0f:55:a2:49:ab UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
You’d be forgiven for reading this as a healthy WiFi that just isn’t getting a DHCP address (at least you would be by me as it was my first thought). A quick look at the out-of-the box /etc/network/interfaces revealed a potential smoking gun:-
auto lo iface lo inet loopback iface eth0 inet dhcp allow-hotplug wlan0 iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf iface default inet dhcp
It looked like wlan0 was set to use a manually assigned IP address rather than DHCP. Simple! Fixing that line and rebooting should solve the problem:-
iface wlan0 inet dhcp
It didn’t. In fact things were now worse. wlan0 didn’t look any different but the wpa_supplicant processes that had previously been running to support it where now nowhere to be found:-
pi@raspberrypi ~ $ ps -afe | grep wpa root 1705 1 0 16:06 ? 00:00:00 /sbin/wpa_supplicant -s -B -P /var/run/wpa_supplicant.wlan0.pid -i wlan0 -W -D nl80211,wext -c /etc/wpa_supplicant/wpa_supplicant.conf root 1852 1 0 16:06 ? 00:00:00 /sbin/wpa_cli -B -P /var/run/wp_action.wlan0.pid -i wlan0 -p /var/run/wpa_supplicant -a /sbin/wpa_action
Time to run to the Google cave.
Pi-Fly
If you’re struggling to get a WiFi connection via the command line, there are a few useful diagnostic tools you can reach for.
The wpa_supplicant process handles roaming across WiFi networks and automatically reconnecting to them when necessary. It is spawned by the network initialisation code if there’s a WiFi configuration present. But you can also run it manually and with diagnostic information turned on to see how it’s talking to your network (or not):-
pi@raspberrypi ~ $ sudo wpa_supplicant -i wlan0 -dd -c /etc/wpa_supplicant/wpa_supplicant.conf wpa_supplicant v1.0 … wlan0: New scan results available wlan0: Selecting BSS from priority group 0 wlan0: 0: 00:1e:74:c7:96:53 ssid='SKY38482' wpa_ie_len=24 rsn_ie_len=0 caps=0x11 level=-89 wlan0: skip - SSID mismatch wlan0: 1: a4:b1:e9:54:12:e7 ssid='TNCAP5412E7' wpa_ie_len=0 rsn_ie_len=20 caps=0x11 level=-91 wps wlan0: skip - SSID mismatch wlan0: No suitable network found
This tells me that it’s not seeing my hidden network and the Google Cave tells me that is because I need to add a line to my wpa_supplicant.conf file to force it to search for my hidden WiFi network:-
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="devsumo" scan_ssid=1 psk="MyPassPhrase" }
Now re-running the wpa_supplicant command shows it’s able to connect to my network:-
pi@raspberrypi ~ $ sudo wpa_supplicant -i wlan0 -dd -c /etc/wpa_supplicant/wpa_supplicant.conf … wlan0: Trying to associate with xx:xx:xx:xx:xx:xx (SSID='devsumo' freq=2462 MHz) … wlan0: State: GROUP_HANDSHAKE -> COMPLETED
Rebooting though still shows wlan0 without an IP address, and suspiciously still no wpa_supplicant processes. This looks like something’s going wrong during network initialisation. A useful approach here is to set the IF_WPA_MAINT_DEBUG environment variable to get extra diagnostic information from the startup scripts and then bounce the wireless interface:-
pi@raspberrypi / $ export IF_WPA_MAINT_DEBUG pi@raspberrypi / $ sudo ifdown wlan0 pi@raspberrypi / $ sudo ifup walnut wpa_supplicant: wpa-roam can only be used with the "manual" inet METHOD run-parts: /etc/network/if-pre-up.d/wpasupplicant exited with return code 1
This tells me why my wpa_supplicant processes aren’t starting but it also appears to suggest that you can’t use DHCP with WiFi. Fortunately (and unsurprisingly) this isn’t actually the case – it’s just managed in a different way. The original /etc/network/interfaces is in fact correct to use manual for this interface:-
iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf iface default inet dhcp
The syntax is a little unobvious but the trick is in the last line, which tells it to use DHCP by default for wireless networks. You can use any name in place of default to create groups of wireless networks to use either static or dynamic configurations by associating an id_str value of the same name with those networks in wpa_supplicant.conf. There’s a good explanation of how to do this on aptosid.com.
Switching it back to manual and rebooting finally gives me a fully functioning WiFi connection:-
pi@raspberrypi ~ $ ifconfig wlan0 wlan0 Link encap:Ethernet HWaddr 00:0f:55:a2:49:ab inet addr:192.168.0.20 Bcast:192.168.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:16 errors:0 dropped:0 overruns:0 frame:0 TX packets:6 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2630 (2.5 KiB) TX bytes:1280 (1.2 KiB)
Other than now having an inet addr line it’s also worth noting that the third line now includes the word RUNNING which hadn’t been there previously. When using the wpa_supplicant process it will show UP even if it isn’t connected to a network. You can easily check the status of the WiFi connection using the wpa_cli command:-
pi@raspberrypi ~ $ wpa_cli status Selected interface 'wlan0' wpa_state=SCANNING address=00:0f:55:a2:49:ab
If it shows a state of SCANNING then it can’t find a network to connect to. If it’s connected it’ll tell you what it’s connected to:-
pi@raspberrypi ~ $ wpa_cli status Selected interface 'wlan0' … ssid=devsumo id=0 mode=station … wpa_state=COMPLETED ip_address=192.168.0.20 …
awesome – I think this is the simplest yet most complete and detailed explanation about how to get WiFi to work! Thanks!