D-Bus Tutorial in C to Communicate with Wpa_Supplicant

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

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.

D-Bus API or C library to control firewalld

Yes, you can issue commands to firewalld via D-Bus. I haven't checked but expect that firewall-cmd is itself implemented as a D-Bus client.

The D-Bus API is extensively documented: https://firewalld.org/documentation/man-pages/firewalld.dbus.html. The documentation should give you a rough idea what can be accomplished through the API. You could try the D-Bus debugger d-feet to interact with firewalld without any code.

GDBus is definitely the easiest way use D-Bus from C but it's still not trivial and firewalld is a fairly complex API: Using it may require some expertise (completely depending on what you need to do).

get bus name as set by dbus_request_name of a message sender


One method I figured is to get a list of all registered names with the ListNames method, then query the unique name for each name with GetNameOwner until a match happens. This should work but I still think that there should be a simpler way of doing this.

That is the correct way to achieve what you want.

There is no method on the org.freedesktop.DBus interface to map from a unique name (for example, :1.5) to a well-known name (for example, org.bluez), because each unique name may be the owner of zero or more well-known names.

Arguably there could be an org.freedesktop.DBus.ListNamesForOwner() method which would map from a unique name to an array of well-known names, but nobody has written that yet.

including wpa_ctrl.h in a C code

These files are part of the hostapd project, and internal header files that won't be installed so you can't just include them after installing the package.

You'd be probably better off just ripping out the parts from wpa_ctrl.h you need. Depending on what you need it might be even better to use e.g. the DBus interface to communicate with wpa_supplicant (if that's what you want).



Related Topics



Leave a reply



Submit