How to change Wi-Fi device for Android

This article describes the integration steps required to connect a Wi-Fi device to with STM32 microcontroller. It mainly describes the impact of integrating the new Wi-Fi solution into Android. It is intended for Distribution Package users.

1 Prerequisite[edit]

The environment must be installed using the Distribution Package adapted to the selected microprocessor device. See the list of Android Distribution Package.

The Wi-Fi device must be connected to the microprocessor device on the application board.

2 Overview[edit]

Android Wi-Fi Overview

The Android Wi-Fi software stack contains:

  • Wi-Fi Driver (hardware dependent) → device driver providing access to the Wi-fi hardware device through the netlink family sockets (AF_NETLINK, nl80211 protocol).
  • Wi-Fi HALs (Hardware Abstraction Layer) → three HAL native components implementing the Android Wi-Fi HIDLs (Hardware Interface Definition Language). The optional Vendor HAL provides Android-specific instructions, the Supplicant HAL provides HIDL access to the wpa_supplicant daemon and the Hostapd HAL provides HIDL access to the hostapd daemon.
  • Wi-Fi Connection Manager (wificond) → stand-alone daemon process managing the Wi-Fi connection. It is accessible through the binder IPC mechanism and communicates with the Wi-Fi driver using standard nl80211 instructions.
  • Wi-Fi system services → several Android system services such as WiFiService for Wi-Fi connection, WifiP2PService for Wi-Fi Direct™ connection, WifiAwareService for Wi-Fi Aware™ (Neighbour Awareness Networking protocol) and WifiRttService implement the Wi-Fi AIDLs (Android Interface Definition Language) in the process context of the System Server. These services interact with the native subsystem using the Wi-Fi HALs.
  • Framework Wi-Fi API → android.net.wifi APIs providing applications with framework level access to the Wi-Fi subsystem. Internally, the code uses client side Wi-Fi AIDLs to interact with the Wi-Fi system services container process through the Binder IPC mechanism.

Please see the Android Wi-Fi guide[1] for complementary information.

3 Integration steps[edit]

The Wi-Fi solution must be integrated in three main steps:

  • Linux kernel integration
  • Android integration
  • Validation

3.1 Linux kernel integration[edit]

The kernel Wi-Fi integration is performed in two steps:

  • Add the Wi-Fi driver to the compilation process
  • Update the device tree

3.1.1 Compile the Linux Wi-Fi driver[edit]

The Wi-Fi subsystem is accessed through a nl80211 driver (netlink socket).

Two options:

  • The Wi-Fi driver is part of the Linux kernel source → select the appropriate config (ex: CONFIG_RTL8XXXU=y for the Realtek RTL8723AU). Refer to Updating the kernel configuration for more information.
  • The Wi-Fi driver is provided separately → add it in the build_kernel.sh script

3.1.2 Update the Linux device tree[edit]

Depending on the selected driver, the device tree (refer to Changing the Device Tree for more information) may need to be updated.

3.2 Android integration[edit]

The Wi-Fi device integration to Android is performed in the following steps:

  • Add properties to give information on the nl80211 interface available
  • Add permissions to allow the initialization of the required Android services
  • Add the Wi-Fi interface (Hardware Abstraction Layer) if available for the required Wi-Fi device
  • Add the Wi-Fi firmware if available for the required Wi-Fi device
  • Configure the Wi-Fi supplicant

3.2.1 Add Android properties[edit]

Two netlink interfaces can be set through the Android properties. For that purpose, add to device.mk the following lines:

PRODUCT_PROPERTY_OVERRIDES += \
    wifi.interface=wlan0 \
    wifi.direct.interface=p2p0 \
    wifi.aware.interface=aware0

Note: They are already the default netlink interfaces, it is not mandatory to set them

3.2.2 Add Android permissions[edit]

Three permissions can be added to ensure that the Wi-Fi services are correctly started:

  • android.hardware.wifi.xml → starts the Wi-Fi service
  • android.hardware.wifi.direct.xml → starts the Wi-Fi Direct service
  • android.hardware.wifi.aware.xml → starts the Wi-Fi Aware service
  • android.hardware.wifi.rtt.xml → starts the Wi-Fi RTT service
  • android.hardware.wifi.passpoint.xml → enable Wi-Fi Passpoint (Hotspot 2.0)


For that purpose, the following lines must be added to device.mk

 PRODUCT_COPY_FILES += \
 frameworks/native/data/etc/android.hardware.wifi.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.xml \
 frameworks/native/data/etc/android.hardware.wifi.direct.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.direct.xml \
 frameworks/native/data/etc/android.hardware.wifi.aware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.aware.xml \
 frameworks/native/data/etc/android.hardware.wifi.passpoint.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.passpoint.xml \
 frameworks/native/data/etc/android.hardware.wifi.rtt.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.wifi.rtt.xml \

3.2.3 Add the Wi-Fi HAL (Hardware Abstraction Layer)[edit]

The Wi-Fi Interface (HAL) must be integrated if any vendor extension is available → generate libwifi-hal-<device name>.so library

Examples of extension services: GSCAN (offload Scan), RTT (Round Trip Time), NAN (Neighbor Aware Networking), RSSI (offload Received Signal Strength Indication) or offload roaming (black list).

The BoardConfig.mk must be updated in consequence:

BOARD_WLAN_DEVICE := <device> # needed if specific wifi_hal is implemented (products available by default in framework/opt/net/wifi/service/Android.mk)

Your Wi-Fi device provider can also provide its own implementation and associated directives.

3.2.4 Add the Wi-Fi device firmware[edit]

Depending on the Wi-Fi solution, a firmware may need to be loaded to the device.

The firmware must be copied to the correct device directory, so that it can be configured through the kernel command line. For that purpose, add the following line to BoardConfig.mk:

 BOARD_KERNEL_CMDLINE += firmware_class.path=/vendor/firmware/

The firmware must be added in the ramdisk (rootfs) to ensure that it is available during the first stage of initialization

 PRODUCT_COPY_FILES += \
 device/stm/$(SOC_FAMILY)/$(BOARD_NAME)/network/wifi/<wifi_firmware>.bin:root/$(TARGET_COPY_OUT_VENDOR)/firmware/<wifi_path>/<wifi_firmware>.bin \
 device/stm/$(SOC_FAMILY)/$(BOARD_NAME)/network/wifi/<wifi_firmware>.$(TARGET_COPY_OUT_VENDOR)/firmware/<wifi_path>/<wifi_firmware>.bin

Note: if the driver is compiled as a module (.ko) and loaded after the on post-fs tag, it is not required to add the firmware to the rootfs

Depending on the selected solution, the firmware may need to be dynamically reloaded. For example, for the selected solution, the following variable in BoardConfig.mk may be required:

WIFI_DRIVER_FW_PATH_STA := <FW PATH> # used only if necessary, gives specific FW for standard station configuration
WIFI_DRIVER_FW_PATH_P2P := <FW PATH> # used only if necessary, gives specific FW for standard peer to peer configuration
WIFI_DRIVER_FW_PATH_AP  := <FW PATH> # used only if necessary, gives specific FW for standard access point configuration

Your Wi-Fi device provider can also provide its own implementation and associated requirements.

3.2.5 Configure the Android service[edit]

The wpa_supplicant service (one driver interface: wlan0, one control interface: /data/misc/wifi/sockets) shall be integrated within the rc file

service wpa_supplicant /vendor/bin/wpa_supplicant \
   -g@android:wpa_wlan0
   interface android.hardware.wifi.supplicant@1.0::ISupplicant default
   interface android.hardware.wifi.supplicant@1.1::ISupplicant default
   interface android.hardware.wifi.supplicant@1.2::ISupplicant default
   socket wpa_wlan0 dgram 660 wifi wifi
   class main
   disabled
   oneshot

The BoardConfig.mk must be updated in consequence:

WPA_SUPPLICANT_VERSION := VER_0_8_X
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_$(BOARD_WLAN_DEVICE) # needed to define if any specific supplicant vendor library is available (stubbed by default)

The current supplicant overlay is located in device/stm/<STM32Series>/<BoardId>/network/wifi/.

  • wpa_supplicant_overlay.conf
disable_scan_offload=1  → used to disable the offloading (not available by default)
p2p_disabled=1 → used to disable the p2p mode (not required)
  • p2p_supplicant_overlay.conf
disable_scan_offload=1  → used to disable the offloading (not available by default)
p2p_search_delay=100  → used to limit the radio usage for p2p search action

3.3 Validation[edit]

The Wi-Fi validation can be performed in the following steps:

  • Validate Kernel integration
  • Validate Android integration
  • Validate Wi-Fi connection using standard Android user interface

3.3.1 Validate the Kernel Integration[edit]

Reminder: the Wi-Fi subsystem is accessed through a netlink socket (nl80211). A tool named iw can be used to check its capabilities.

Open a shell console on the remote device:

 adb shell 

Instruction examples (see the iw man page[2] for more details):

 iw list → lists all the available information on nl80211 socket (incl supported ciphers and instructions)
 iw wlan0 scan → scan operation (grep SSID to get only SSID)
 iw wlan0 connect <ssid> → connect to the defined SSID if not protected (otherwise wpa_supplicant shall be used)
 iw dev wlan0 link → gives wlan0 connection state

3.3.2 Validate the Android Integration[edit]

Several tests are available, please refer to the associated official documents:

3.3.3 Check the Wi-Fi connection[edit]

Enable the Wi-Fi connection in Android settings and try to connect to a known access point (see the Android One available answers for more information [5]).

3.4 Debugging Tips[edit]

It's possible to enable or disable the "Verbose" mode of the Wi-Fi framework (wificond) logging through the Settings menu: System->Developer options->Enable Wi-Fi Verbose Logging

It's possible to increase the verbosity of the wpa_supplicant changing the init.*.rc file adding -d option:

service wpa_supplicant /system/bin/wpa_supplicant \
   -d -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
   -I/system/etc/wifi/wpa_supplicant_overlay.conf -O/data/misc/wifi/sockets \
   -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0

4 References[edit]