Switching the wifi mode between AP and client connection

Hi,

is there a way to switch the Yún between acting as a Wifi AP vs. connecting to the given Wifi-network using the Bridge/Process API?

I'm working on a project using the Yún as a datalogger with a (more or less) complex website running on a server on the Yún itself. At the same time the device is in a handheld housing with a small LCD screen so you can carry it around and measure outside and far away from any Wifi network. Now I would like to be able to switch the Yún (without resetting/rebooting!) to the AP mode so I can connect with a smartphone/tablet to it and still access the website in order to give me advanced stats about the logged/measured data.

Thank you!

I have a potential application with a similar set of requirements: I need the Yun to connect to an access point so it has an internet connection to send data to a server, but it also needs to act as an access point so that a smartphone/tablet can connect to it and be served locally hosted web pages. Ideally, both should be active at one time.

The Yun's WiFi can be both a client and a host at the same time. I've done it on my router using dd-wrt, and on the Yun's OpenWRT. The problem is that there are a couple catches, one more serious than the other.

The first catch is that both the client and access point interfaces must be on the same channel, which isn't too big of a problem if both are set up with automatic channel numbers: the Yun's client interface will automatically be set to the right channel when it associates to its external access point, then the Yun's access point interface will be set to the same channel.

The more serious catch is that if the Yun's client mode connection to the access point is lost, it also brings down the Yun's access point interface. This is apparently because the WiFi driver is spending all it's time trying to connect the client interface to the access point, that it can't service the access point mode. (Or it's a matter of not knowing which channel to use?)

For my application, losing the local access point when moving outside of the range of the external access point is a problem. From the sound of it, that may be a serious problem for your application. If there were a way to figure out this problem, it would be an ideal situation for both of us.

For your application, you should be able to write a Python script to change your WiFi configuration (or switch between two saved configurations.) It may be as simple as writing two wireless configuration files. Then the script would bring down the WiFi interface, copy the needed configuration file into place, then bring up the interface again. I don't currently have access to my Yun so I can't give an example. Maybe someone will be by soon who can give some tips off of the top of their head.

Thanks for your comment.

ShapeShifter: For my application, losing the local access point when moving outside of the range of the external access point is a problem. From the sound of it, that may be a serious problem for your application. If there were a way to figure out this problem, it would be an ideal situation for both of us.

Well my application does not require both the local AP and the external Wifi connection, so it does not matter if there is no type of Wifi connection to the Yún possible for a limited amount of time. To simplify it a little bit:

  • If the Yun does not find the preconfigured access point anymore it should bring up its own access point. This will also require the client to change its Wifi network to the AP provided by the Yún but this is no problem in this case.
  • If the Yun is again in the range of the external access point, it should disable its own access point and connect to that network.

In both cases the timing is not critical, so it would be sufficient to have a daemon checking the situation every minute.

For your application, you should be able to write a Python script to change your WiFi configuration (or switch between two saved configurations.) It may be as simple as writing two wireless configuration files. Then the script would bring down the WiFi interface, copy the needed configuration file into place, then bring up the interface again. I don't currently have access to my Yun so I can't give an example. Maybe someone will be by soon who can give some tips off of the top of their head.

I would be glad if someone could provide a short example as I'm not that much into configuring wifi interfaces using config files ;)

Hawkes: In both cases the timing is not critical, so it would be sufficient to have a daemon checking the situation every minute.

I'll leave this part as an exercise to the reader. :smiling_imp: But if you get something working, I'd love to see it as it may help me.

I would be glad if someone could provide a short example as I'm not that much into configuring wifi interfaces using config files ;)

I've created different configuration files in the past, and manually copied them in place to change WiFi modes. I just wrote a very simple script to automate switching modes. Here's basically what I did:

  • Go into the Yun's advanced configuration web pages, set up the first mode as desired, then click "Save and Apply." This creates the configuration file /etc/config/wireless
  • From the SSH command line, copy the configuration file to a new file. I put it on the SD card at /mnt/sda1/wireless/ but it doesn't really matter where. Give it a meaningful name.
  • Go back into the Yun's advanced configuration web pages, and set up the the next mode as desired. Click "Save and Apply."
  • From the SSH command line, copy the configuration file to a new file.
  • Create the mode change script (listed below) and make it executable (chmod +x)

The script to change modes: /mnt/sda1/wireless/changeWiFi

#!/bin/ash

# Script to change the WiFi configuration
# Parameter is the name of the new WiFi configuration file
# Wifi interface is brought down, the new configuration file
# is copied into place, then the WiFi is started again.

# Stop the current WiFi configuration
wifi down

# Copy the new configuration file into place
cp $1 /etc/config/wireless

# Start the new WiFi configuration
wifi

Now, whenever you want to change modes, execute the change script file giving the name of the saved configuration as a parameter. You can call this script from the Arduino side using the Bridge's Process class, or if you write your network monitor daemon on the Linux side, you can call it directly from your daemon.

An example:

The saved client mode configuration file: /mnt/sda1/wireless/wireless.client

config wifi-device 'radio0'
        option type 'mac80211'
        option hwmode '11ng'
        option path 'platform/ar933x_wmac'
        option htmode 'HT20'
        list ht_capab 'SHORT-GI-20'
        list ht_capab 'SHORT-GI-40'
        list ht_capab 'RX-STBC1'
        list ht_capab 'DSSS_CCK-40'
        option disabled '0'
        option channel 'auto'
        option country 'US'
        option txpower '16'

config wifi-iface
        option device 'radio0'
        option network 'lan'
        option mode 'sta'
        option encryption 'psk2'
        option key 'ClientModePassword'
        option ssid 'ClientModeSSID'

The saved access point mode configuration file: /mnt/sda1/wireless/wireless.AP

config wifi-device 'radio0'
        option type 'mac80211'
        option hwmode '11ng'
        option path 'platform/ar933x_wmac'
        option htmode 'HT20'
        list ht_capab 'SHORT-GI-20'
        list ht_capab 'SHORT-GI-40'
        list ht_capab 'RX-STBC1'
        list ht_capab 'DSSS_CCK-40'
        option disabled '0'
        option channel 'auto'
        option country 'US'
        option txpower '16'

config wifi-iface
        option device 'radio0'
        option network 'lan'
        option encryption 'psk2'
        option ssid 'ApModeSSID'
        option mode 'ap'
        option key 'ApModePassword'

Changing modes: (using SSH command line)

[b][color=blue]root@Arduino:/# [/color][color=red]/mnt/sda1/wireless/changeWiFi /mnt/sda1/wireless/wireless.client[/color][/b][color=blue]
Successfully initialized wpa_supplicant
[b]root@Arduino:/# [/b][/color][color=red][b]pretty-wifi-info.lua[/b][/color][color=blue]
Current WiFi configuration
SSID: ClientModeSSID
Mode: Client
Signal: 0%
Encryption method: -
Interface name: wlan0
Active for: 0 minutes
MAC address: 90:A2:DA:F0:32:D2
RX/TX: 0/0 KBs
[b]root@Arduino:/# [/b][/color][color=red][b]/mnt/sda1/wireless/changeWiFi /mnt/sda1/wireless/wireless.AP[/b][/color][color=blue]
Configuration file: /var/run/hostapd-phy0.conf
wlan0: interface state UNINITIALIZED->COUNTRY_UPDATE
ACS: Automatic channel selection started, this may take a bit
wlan0: interface state COUNTRY_UPDATE->ACS
wlan0: ACS-STARTED
wlan0: ACS-COMPLETED freq=2442 channel=7
Using interface wlan0 with hwaddr 90:a2:da:f0:32:d2 and ssid "ApModeSSID"
wlan0: interface state ACS->ENABLED
wlan0: AP-ENABLED
[b]root@Arduino:/# [/b][/color][b][color=red]pretty-wifi-info.lua[/color][/b][color=blue]
Current WiFi configuration
SSID: ApModeSSID
Mode: Master
Signal: 0%
Encryption method: WPA2 PSK (CCMP)
Interface name: wlan0
Active for: 0 minutes
MAC address: 90:A2:DA:F0:32:D2
RX/TX: 0/0 KBs
[b]root@Arduino:/#[/b]
[/color]

As an alternative, you could write your "change mode" script to issue all of the UCI commands to change each individual wireless configuration item (mode, SSID, password, etc.) But while my copy file method uses a bit more disk space to store copies of the configuration files, on the whole I think it's a much simpler method and easier to maintain. In the future, if you want to update any of the configurations, it's a simple matter of starting that configuration, using the web interface to make and apply the changes, and then saving a new copy of the configuration file. That's a lot simpler than editing the script file and changing all of the UCI commands! I think this is a much more maintainable solution.

Good luck!

Sounds like a good solution. I'll definitely give it a try.