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
- 2 Overview
- 3 Integration steps
- 3.1 Linux kernel integration
- 3.2 Android integration
- 3.3 Validation
- 3.4 Debugging Tips
- 4 References
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.
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 for complementary information.
3 Integration steps
The Wi-Fi solution must be integrated in three main steps:
- Linux kernel integration
- Android integration
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).
- The Wi-Fi driver is part of the Linux kernel source → select the appropriate config (ex:
CONFIG_RTL8723BU=yfor 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
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
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).
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
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:
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
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
disable_scan_offload=1 → used to disable the offloading (not available by default) p2p_disabled=1 → used to disable the p2p mode (not required)
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
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 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 ).
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