Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing an external program to interface with wpa_supplicant in C++

As I understand it one can simply link wpa_ctrl.c into an external program and then you are able to use it's functions to control and receive information from wpa_supplicant.

Could someone please provide an example, preferably in C++, how you would:

  1. Link the external program to the wpa_ctrl.c file.
  2. What the code would look like to do a 'scan' and then print 'scan_results'.

I'm new to coding on an embedded linux platform and there are no examples of this anywhere. Many thanks in advance!

like image 311
Nimjox Avatar asked Apr 23 '14 16:04

Nimjox


1 Answers

The program wpa_cli is an example of exactly what you want. The wpa_supplicant project support the V=1 option to see what is needed to create this executable. Here is the result for my ARM build,

gcc -c -o wpa_cli.o -MMD -O2 -Wall -g -I src -I src/utils \
  -Iusr_ARM/include/libnl3 \
  -DCONFIG_BACKEND_FILE -DCONFIG_IEEE80211W  -DCONFIG_DRIVER_WEXT \
  -DCONFIG_WIRELESS_EXTENSION  -DCONFIG_DRIVER_NL80211 -DCONFIG_LIBNL20 \
  -DEAP_PSK -DIEEE8021X_EAPOL -DCONFIG_SHA256 -DCONFIG_CTRL_IFACE \
  -DCONFIG_CTRL_IFACE_UNIX  -DCONFIG_SME \
   wpa_cli.c

gcc  -o wpa_cli wpa_cli.o ../src/common/wpa_ctrl.o ../src/utils/wpa_debug.o \
   ../src/utils/common.o ../src/utils/os_unix.o ../src/utils/eloop.o \
   ../src/utils/edit_simple.o -lrt

Substitute your paths to get headers for the version of the wpa_supplicant used on your target ARM device (in the first command). Link with all of the object files listed in the second command and link with the real-time library (with -lrt). You can also look at the wpa_cli.c for your version of the wpa_supplicant to get examples of how to send commands to the supplicant process.

The object list includes wpa_ctrl.o (as you guessed) and many others. Some of them may not be needed, depending on features you use, but I would start with the complete list and then trim them after you have a functioning example.

The license is the generous BSD on this source.

Here is wpa_cli_cmd_scan() which sends the scan request,

static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
    return wpa_cli_cmd(ctrl, "SCAN", 0, argc, argv);
}

You probably also want the scan_results; it is in the same file as wpa_cli_cmd_scan_results().

The API is also well documented under wpa_supplicant control interface, where you can extend your working example. Make sure you get source that matches the version of the wpa_supplicant in use on your system. The commands above are for an eglibc Linux system; It looks like bionic (Android library) supplies the -lrt by default. If you can run the commands, rm wpa_cli.o; rm wpa_cli; make V=1 in the wpa_supplicant directory of a build for your device you will see the exact commands needed.

You probably don't need the edit_simple.o file. However, the eloop is likely needed to get unsolicited events from the drivers when the scan request is completed; at least if you want to work with many different Wifi chips. The steps are,

  1. Send SCAN.
  2. Wait for <SCAN_COMPLETE>.
  3. Send SCAN_RESULTS.
like image 89
artless noise Avatar answered Oct 21 '22 12:10

artless noise