Merlin
Merlin

Reputation: 11

Connect via wpa_supplicant from Lua Application and .sh scripts

On my devices since a few months we have installed WiFi modules, from user interface you can scan available wifi networks and connect to one of them. If the connection is successful I store data about that connection to make it possible to automatically reconnect at a later device startup.

My UI application is ralized in LUA and from code I have the ability to run linux commands (I work in Buildroot environment), for various reasons I don't have connman available so I manage the network connection with wpa_supplicant.

Currently let's say my solution is pretty lousy, it works but it certainly can't be called a good job.

I will try to summarize it quickly: Every 10 seconds I update the list of available networks with the command

iwlist wlan0 scan

then I update the list of available wifi and their characteristics. In parallel I have another routine (Lua) that every 5 seconds checks the connection status, if the connection is established OK, otherwise it tries to establish a connection with one of the stored networks. To establish a connection I use wpa_supplicant, the problem is that wpa_supplicant is not instantaneous and I need some time frame (variable) to understand if the connection has been established or not.

the portion of code that manage this part is the following:

if(counter_500ms % 10 == 0 )then
    local file = io.open("/tmp/connesso","r")
    if(not(file)) then
        Connesso_A_Internet = false
    else
        local lettura = tonumber(file:read("*a"))
        file:close()
        if(lettura == 1)then
            print("connesso")
            Connesso_A_Internet = true
            Tempo_Last_Check_Connection = gre.mstime() / 1000
        else
            if(Connesso_A_Internet and math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) >= 20)then
                Connesso_A_Internet = false
                First_Connection_Wifi(mapargs)
            elseif(Connesso_A_Internet and math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) < 10)then
                Connesso_A_Internet = true
            else
                Connesso_A_Internet = false
                if( math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) >= 20)then
                    First_Connection_Wifi(mapargs)
                end
            end
            
        end
    end
end

-----
function First_Connection_Wifi(mapargs)
    -- enter only if internet connection is not present
    if(not Connesso_A_Internet)then
        local index = 0
        local f,p
        local nome_temp = nil
        -- parse the structure that contains information about available internet connection
        for i=1,#struttura_reti do
            local stringa_da_cercare = struttura_reti[i].name
            -- extract the ssid of available connections
            stringa_da_cercare = string.gsub(stringa_da_cercare," ","\\ ")

            -- check if this ssid has been used in the past
            local file = io.open("/mnt/tables/wpa_supplicant_"..stringa_da_cercare..".conf","r")
            if(not(file)) then
                -- this ssid has never been used in the past
                -- it seems that in this case a [sh] process is addes to ps output
                print("non c'è file", struttura_reti[i].name)
            else
                -- this ssid has never been used in the past since I have a .conf file with connection information
                print("c'è il file ->",struttura_reti[i].name)
                nome_temp = struttura_reti[i].name
                file:close()
                break
            end
        end

        -- if I found a ssid in memory I try to connect to this network
        -- since the connection is established, the [sh] problem is solved
        if(nome_temp ~= nil)then
            os.execute("killall wpa_supplicant &")

            gre.timer_set_timeout(function()
                Tempo_Last_Check_Connection = gre.mstime() / 1000
                Rete_In_Connessione = nome_temp
                local stringa_da_cercare = nome_temp
                stringa_da_cercare = string.gsub(stringa_da_cercare," ","\\ ")
                os.execute("wpa_supplicant -B -D nl80211 -i wlan0 -c /mnt/tables/wpa_supplicant_"..stringa_da_cercare..".conf &")
            end,500)
        end
    end
end

To understand if the connection is established I run the following script:

#!/bin/sh
FirstIP="8.8.8.8" #(Google public DNS)
SecondIP="8.8.4.4" #(OpenDNS public DNS)
IDX="208"
DomoIP="192.168.1.103"
DomoPort="8080"

pingo="ping -c 5 -w 1 -q "$FirstIP"";
if $pingo | grep -E "min/avg/max" > /tmp/OutputPing;
then
    echo "1" > /tmp/connesso
else
    #echo "--> No response from first IP ("$FirstIP"), now trying second one ("$SecondIP")"
      pingo="ping -c 5 -w 1 -q "$SecondIP"";
      if $pingo | grep -E "min/avg/max" > /tmp/OutputPing;
      then
      echo "1" > /tmp/connesso

   else
      echo "0" > /tmp/connesso
   fi
fi

By checking the value of /tmp/connection I am able to determine whether the connection has been established or not. Now, since this solution works but seems quite idiotic, how can I use wpa_supplicant more intelligently?

Upvotes: 0

Views: 65

Answers (1)

Arnout
Arnout

Reputation: 3484

The best approach is to not restart wpa_supplicant all the time, but instead use wpa_cli to dynamically reconfigure it.

wpa_cli connects to a socket that wpa_supplicant listens on - instead of using wpa_cli, you can also connect to this socket directly from your Lua code. That gives you a bit more flexibility.

To be able to use either wpa_cli or the sockets, you need to enable this during the build. Use the Buildroot option BR2_PACKAGE_WPA_SUPPLICANT_CLI for this (it automatically enables BR2_PACKAGE_WPA_SUPPLICANT_CTRL_IFACE which is what you need to listen on the socket).

Upvotes: 0

Related Questions