WiFi Configuration in Embedded Linux Using C++

The previous article “Analysis of WiFi Configuration Scripts in Embedded Linux” introduced how to configure WiFi on embedded Linux development boards using shell scripts to call tools like wpa_supplicant.

This article will introduce how to achieve the same functionality through C++ programming.

WiFi Configuration in Embedded Linux Using C++

1. Preparation

My development board previously had a script set to automatically start WiFi configuration at boot. To facilitate testing of C++ programming, you can disable the automatic script.

In the /etc/init.d directory, I previously added a file named S99myinit and commented out the line that starts the WiFi configuration script.

#!/bin/sh

#fltest_wifi.sh -i wlan0 -s "wifi_name" -p wifi_password

If network access is needed, it can be manually started first.

fltest_wifi.sh -i mlan0 -s "MERCURY_3394" -p "2H2+O2=2H2O"

Additionally, when I was studying this development board from Feilin, I set up a cross-compilation environment in Ubuntu. During compilation, I input commands like the following to specify the cross-compilation toolchain:

export PATH=/home/xxpcb/myTest/OK3568/gcc_aarch64/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH
aarch64-linux-gnu-g++ test_wifi.cpp -o test_wifi

2. Writing Code

2.1 Main Function

Based on the WiFi configuration flow of the shell script, I wrote the corresponding C++ code. Let’s first look at the main function:

#include <unistd.h>
#include <cstdlib> // For calling system commands
#include <fstream>
#include <iostream>
#include <string>

#define NET_PORT "mlan0"

int main(int argc, char *argv[])
{
    std::string ssid = "MERCURY_3394";
    std::string password = "2H2+O2=2H2O";
    printf("[%s] argc:%d\n", __func__, argc);
    if (argc > 1)
    {
        if (argc == 3)
        {
            ssid = argv[1];
            password = argv[2];
        }
        else
        {
            printf("[%s] please input para: ssid password\n", __func__);
            return -1;
        }
    }
    printf("[%s] ssid:%s password:%s\n", __func__, ssid.c_str(), password.c_str());

    SYS_CMD(std::string("/etc/init.d/S80dnsmasq stop > /dev/null"));
    CreateWpaConfig(ssid, password);
    ConnectWiFi();

    return 0;
}
  • There is a default WiFi name and password, and it also supports runtime parameters. If corresponding parameters are provided, it will use the WiFi name and password from the parameters.
  • First, execute S80dnsmasq stop (as described in the previous article).
  • Then create a wpa configuration file.
  • Finally, connect to the network.

2.2 Executing Linux Commands

In C++, to execute Linux commands, you can use std::system. To facilitate the analysis of program execution, print the command being executed each time a Linux command is run. Here, a function and macro definition are encapsulated to print which function called which command:

#define SYS_CMD(cmd) SysCmd(__func__, cmd)

int SysCmd(const char *funcName, std::string cmd)
{
    printf("[%s] do %s\n", funcName, cmd.c_str());
    return std::system(cmd.c_str());
}

2.3 Creating the WPA Configuration File

#define WPA_CONF_FILE "/etc/wpa_supplicant.conf"

void CreateWpaConfig(const std::string &ssid, const std::string &password)
{
    printf("[%s] in\n", __func__);
    std::ofstream configFile(WPA_CONF_FILE);
    if (configFile.is_open())
    {
        configFile << "ctrl_interface=/var/run/wpa_supplicant" << std::endl;
        configFile << "ctrl_interface_group=0" << std::endl;
        configFile << "update_config=1" << std::endl;

        configFile << "network={" << std::endl;
        configFile << "    ssid=\"" << ssid << "\"" << std::endl;
        configFile << "    psk=\"" << password << "\"" << std::endl;
        configFile << "key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE" << std::endl;
        configFile << "group=CCMP TKIP WEP104 WEP40" << std::endl;
        configFile << "}" << std::endl;

        configFile.close();
    }
    else
    {
        printf("write config file err\n");
    }
    printf("[%s] out\n", __func__);
}

The main function is to open “/etc/wpa_supplicant.conf” and write the corresponding configuration items.

2.4 WiFi Configuration Processing

Call various Linux commands to configure WiFi.

void ConnectWiFi()
{
    printf("[%s] in\n", __func__);
    std::string tmpCmd;
    // down NET_PORT
    tmpCmd = "ifconfig " + std::string(NET_PORT) + " down > /dev/null";
    if (-1 == SYS_CMD(tmpCmd.c_str()))
    {
        printf("[%s] do %s failed!\n", __func__, tmpCmd.c_str());
        goto END;
    }

    // stop wpa_supplicant
    tmpCmd = "ps -fe|grep wpa_supplicant |grep -v grep > /dev/null";
    if (0 == SYS_CMD(tmpCmd.c_str()))
    {
        tmpCmd = "kill -9 $(pidof wpa_supplicant)";
        if (-1 == SYS_CMD(tmpCmd.c_str()))
        {
            printf("[%s] do %s failed!\n", __func__, tmpCmd.c_str());
            goto END;
        }
    }

    // up NET_PORT
    tmpCmd = "ifconfig " + std::string(NET_PORT) + " up > /dev/null";
    if (-1 == SYS_CMD(tmpCmd.c_str()))
    {
        printf("[%s] do %s failed!\n", __func__, tmpCmd.c_str());
        goto END;
    }

    // start wpa_supplicant
    tmpCmd = "(wpa_supplicant -Dnl80211,wext -i" + std::string(NET_PORT) + " -c " +
             std::string(WPA_CONF_FILE) + " >/dev/null) &&";
    if (-1 == SYS_CMD(tmpCmd.c_str()))
    {
        printf("[%s] do %s failed!\n", __func__, tmpCmd.c_str());
        goto END;
    }
    sleep(3);

    // check status
    tmpCmd =
        "wpa_cli -i" + std::string(NET_PORT) + " status |grep COMPLETED |grep -v grep > /dev/null";
    if (-1 == SYS_CMD(tmpCmd.c_str()))
    {
        printf("[%s] do %s failed!\n", __func__, tmpCmd.c_str());
        goto END;
    }

    // udhcpc
    tmpCmd = "udhcpc -i" + std::string(NET_PORT) + "";
    if (-1 == SYS_CMD(tmpCmd.c_str()))
    {
        printf("[%s] do %s failed!\n", __func__, tmpCmd.c_str());
        goto END;
    }

END:
    printf("[%s] out\n", __func__);
}

The processing flow can be summarized in the following flowchart:

WiFi Configuration in Embedded Linux Using C++

This only describes the normal situation; if there is an error in the process, it needs to exit abnormally.

3. Testing and Verification

First, run the test program without any parameters, using the default WiFi name and password for connection. The final IP address is 192.168.5.111.

Using a mobile phone, create another hotspot (simulating another WiFi), then specify the mobile hotspot’s name and password as parameters to run the test program. The final IP address is 192.168.174.243.

WiFi Configuration in Embedded Linux Using C++

4. Conclusion

This article introduced how to use C++ programming to implement WiFi configuration in embedded Linux development by calling tools like wpa_supplicant. By writing test routines and conducting actual tests, the functionality of the code was verified.

WiFi Configuration in Embedded Linux Using C++

END

Author: xxpcb
Source: Programmer Loves Learning
Copyright belongs to the original author. If there is any infringement, please contact for deletion..
Recommended Reading
How Fast Can GPIO Toggle?
I Don’t Want to Do This Project Again!!!
Didn’t Expect the Recently Popular DeepSeek Can Really Analyze Circuits!
→ Follow to Stay Updated ←

Leave a Comment