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

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

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) 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

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

  • Linux kernel integration
  • Android integration
  • Validation

3.1 Linux kernel integration

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

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_RTL8723BU=y for the Realtek RTL8723BU, for kernel version ≤ 4.9). 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

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

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

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

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

3.2.2 Add Android permissions

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

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

PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
frameworks/native/data/etc/android.hardware.wifi.direct.xml:system/etc/permissions/android.hardware.wifi.direct.xml \
frameworks/native/data/etc/android.hardware.wifi.aware.xml:system/etc/permissions/android.hardware.wifi.aware.xml \

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

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

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=/etc/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/<STM32Series>/<BoardId>/network/wifi/<wifi_firmware>.bin:root/system/etc/firmware/<wifi_path>/<wifi_firmware>.bin \
device/stm/<STM32Series>/<BoardId>/network/wifi/<wifi_firmware>.bin:system/etc/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

The supplicant is started with two possible options (see wpa_supplicant(8) - Linux man page for more information):

  • wpa_supplicant (one driver interface: wlan0, one control interface: /data/misc/wifi/sockets) → only in case the wifi needs a special permission
service wpa_supplicant /system/bin/wpa_supplicant \
   -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
  • p2p_supplicant (two driver interfaces: wlan0 and p2p0, one control interface: /data/misc/wifi/sockets) → in case of wifi and wifi.direct permissions
service p2p_supplicant /system/bin/wpa_supplicant \
   -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
   -I/system/etc/wifi/wpa_supplicant_overlay.conf -O/data/misc/wifi/sockets \
   -N -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \
   -I/system/etc/wifi/p2p_supplicant_overlay.conf \
   -puse_p2p_group_interface=1 \
   -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0

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

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

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:

PC $> adb shell 

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

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

3.3.2 Validate the Android Integration

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

3.3.3 Check the Wi-Fi connection

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

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


Attachments

Discussions