Android Wi-Fi — IP forward — ndc — netd


http://trac.gateworks.com/wiki/Android/wireless


Android uses the standard hostapd and wpa_supplicant users-space daemons for Access Point and authentication management. These are fairly close forks of the upstream projects with some changes specifically for Android. Source for both is currently in the external/wpa_supplicent_8 directory. Currently this relates most closely to the version 2.1-devel branch.

The Android network daemon netd (source in /system/netd) manages the overall Linux based network configuration listening for commands over a socket interface. There is a Network Daemon Command shell application, ndc that can be used to send/receive commands via command-line.

The wifi legacy module in hardware/hardware_liblegacy/wifi.c implements the API defined in hardware/libhardware_legacy/include/hardware_legacy/wifi.h

Build-time Configuration

The BoardConfig.mk file for your build target defines the details of the configuration of hostapd and wpa_supplicant used in the build process.

The Gateworks Android BSP defines the following:

# wireless device (used by various modules to include per-device support)
BOARD_WLAN_DEVICE := wl12xx_mac80211

# Supplicant
WPA_SUPPLICANT_VERSION := VER_0_8_X
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_wl12xx
# skip populating rtl/conf files
SKIP_WPA_SUPPLICANT_RTL := y
SKIP_WPA_SUPPLICANT_CONF := y

# AP
HOSTAPD_VERSION                  := VER_0_8_x
BOARD_HOSTAPD_DRIVER             := NL80211
BOARD_HOSTAPD_PRIVATE_LIB        := lib_driver_cmd_wl12xx
  • the wl12xx configuration and library are fairly mac80211 compliant and thus should provide support for all mac80211 drivers we include
  • the 'PRIVATE_LIB's are used when communicating with the driver and allow for easy customization

Additional defines can be used for drivers that require specific kernel modules to be loaded or firmware to be loaded for various operation modes. The actual loading of the modules and firmware is done by wifi.c:

# kernel modules
WIFI_DRIVER_MODULE_PATH - full path of kernel module(s)
WIFI_DRIVER_MODULE_NAME - kernel module name (w/o the ko)
WIFI_DRIVER_MODULE_ARG - kernel module params
WIFI_DRIVER_P2P_MODULE_ARG

# firmware
WIFI_FIRMWARE_LOADER - firmware loader
WIFI_DRIVER_FW_PATH_PARAM - params to pass to fw loader
WIFI_DRIVER_FW_PATH_AP - full path to AP firmware
WIFI_DRIVER_FW_PATH_STA - full path to STA firmware
WIFI_DRIVER_FW_PATH_P2P - full path to P2P firmware
  • Note by default these are all blank or null meaning not used and the Gateworks BSP does not define these meaning it supports wireless devices that either need no module/firmware loading or that it is assumed that was done during init.sh

Android Framework API

The Android framework talks to {{{netd}} via the NetworkManagementService class

The WifiManager class provides the primary API for managing al aspects of Wi-Fi connectivity. To perform operations that pertain to network connectivity at an abstract level use ConnectivityManager which answers queries about the state of network connectivity and notifies applications when network connectivity changes.

The WifiConfiguration class reprsents a configured Wi-Fi network, including the security configuration. Android is not intended to provide a build that is suitable for all wireless devices and you may find that customization via the above is necessary.

Packages

The Android modules/packages required for wireless are:

  • client mode: wpa_supplicant
  • access point mode: hostapd hostapd_cli dnsmasq iptables

Firmware and Kernel Module loading

The libhardware_legacy module provides an API used by the Android framework that facilitates kernel module loading, firmware loading, wpa_supplicant service management, and dhcp service management. The module is heavily configurable for specific wireless devices at build-time through:

  • BoardConfig.mk variables:
    # kernel Module
    WIFI_DRIVER_MODULE_NAME
    WIFI_DRIVER_MODULE_PATH
    WIFI_DRIVER_MODULE_ARG
    
    # Firmware
    WIFI_FIRMWARE_LOADER
    WIFI_DRIVER_FW_PATH_STA
    WIFI_DRIVER_FW_PATH_AP
    WIFI_DRIVER_FW_PATH_P2P
    WIFI_DRIVER_FW_PATH_PARAM
    
  • functions and their native JNI mappings via WifiNative class:
    • driver loading/unloading (used by android_net_wifi_WifiNative.cpp)
      • wifi_load_driver() / loadDriver
      • wifi_unload_driver() / unloadDriver
      • is_wifi_driver_loaded() / isDriverLoaded
    • supplicant (used by android_net_wifi_WifiNative.cpp)
      • wifi_start_supplicant() / startSupplicant
      • wifi_stop_supplicant() / killSupplicant
      • wifi_connect_to_supplicant() / connectToSupplicantNative
      • wifi_close_supplicant_connection() / closeSupplicantConnectionNative
    • configuration (used by android_net_wifi_WifiNative.cpp)
      • wifi_wait_for_event() / waitForEventNative
      • wifi_command() / doBoolenaCommandNative / doIntCommandNative / doStringCommandNative
    • DHCP
      • do_dhcp_request()
      • get_dhcp_error_string()
    • firmware loading (used by SoftapController.cpp)
      • wifi_get_fw_path()
      • wifi_change_fw_path()
  • paths for the user-space daemons are stored in wifi.c

Client Mode

Android uses the standard wpa_supplicant users-space daemon for Access Point and authentication management on the client-side.

Configuration

The wpa_supplicant.conf file is stored in /data/misc/wifi/wpa_supplicant.conf and used by the WifiConfigStore class and the SettingsBackupAgent class

Operation

The wpa_supplicant application runs as a backgaround daemon launched by the Android init process. It is communicated with via a socket.

Android UI

You can use Wireless Networking Client support via the Settings App: Settings -> Wi-Fi. You must enable Wi-Fi and configure one or more Wi-Fi networks at which point the NetworkManagementService? will handle the associations.

Android Application

An Application can use Wireless Client mode via the WifiConfiguration class (representing a configured Wi-Fi network including security) and the WifiManager class functions:

command-line

From a command-line perspective you can manually configure and launch wpa_supplicant if you wish:

# restore default wpa_supplicant.conf and start wpa_supplicant service
cp /system/etc/wifi/wpa_supplicant.conf /data/misc/wifi/wpa_supplicant
chmod 660 /data/misc/wifi/wpa_supplicant.conf
chwon system.wifi /data/misc/wifi/wpa_supplicant.conf
start wpa_supplicant

Access Point Mode

Android uses the hostapd users-space daemon for Access Point and authentication management on the AP side. For a DHCP server it uses the typical dnsmasq server.

The hostapd application provides the Access Point management and is managed by the netd SoftapController class which accepts the following commands:

  • startap - starts hostapd
  • stopap - stops hostapd
  • fwreload <STA|AP|P2P> - reload firmware for specified operating mode
  • status - returns if AP is running or not
  • set <wlan iface> <SSID <hidden|broadcast> <channel> <wpa2?-psk|open> <passphrase> - configure AP

The dnsmasq application provides a DHCP server and is managed by the netd TetherController class which also manages iptables.

The netd TetherController class accepts the following commands:

which accesps the following commands.

  • tether stop - stop tethering
  • tether start - start tethering
  • tether status - report tether status
  • tether interface add <iface> - add an interface to the tether
  • tether interface remove <iface> - remove an interface from the tether
  • tether interface list - list tethered interfaces
  • tether dns set <dns1> <...> - add 1 or more dns forwarders
  • tether dns list - list dns forwarders

Network Address Translation (NAT) is provided by the netd NatController class which uses the iptables shell command and accepts the following commands:

  • nat enable <internal interface> <externalinterface> [<route-rules...>] - enable NAT
    • route-rules take the form of: <action> <addr> what will be used with the ip tool as: ip rule <action> from <addr> table
  • nat disable <internal interface> <externalinterface> - disable NAT

Configuration

The hostapd.conf file is stored in /data/misc/wifi/hostapd.conf and used by the SoftapController class.

The dnsmasq application is launched by netd with all configuration available on the cmdline. It will store lease information in /data/misc/dhcp/dnsmasq.leases

When configuration through the Android UI, the Settings application (Settings -> Wireless & Networks -> More... -> Tethering & portable hotspot -> Set up Wi-Fi hotspot) will store the SSID and Passkey settings in the /data/misc/wifi/softap.conf file which are used to dynamically create /data/misc/wifi/hostapd.conf.

Operation

Unlike other system services that are started from Android's init process, hostapd is started on-demand by the Network Daemon netd via it's !SoftapController class when it receives the softap startap command.

This command is sent to netd when the NetworkManagementService startAccessPoint function is called.

Android UI

From an Android UI perspective, you can enable an Access Point (aka Hotspot) and NAT routing (aka Tethering) via the Settings Application:

  1. Goto Settings -> Wireless & Networks -> More... -> Tethering & portable hotspot -> Set up Wi-Fi hotspot and specify your SSID and security settings
  1. Goto Settings -> Wireless & Networks -> More... -> Tethering & portable hotspot -> Portable Wi-Fi hotspot

Note that enabling the Wi-Fi hotspot via the Settings GUI will not 'stick' and again be enabled on re-boot by design.

Android Application

An application can use the WifiManager class to manage an Access Point:

If your wireless device requires module or firmware loading, netd will do this as well by calling fwreload <STA|AP|P2P> using the API defined in hardware/libhardware_legacy/include/wifi.h however note that the firmware load command and patches for each option are a build-time option using paths and arguments defined in BoardConfig.mk. By default these are all blank meaning no firmware or modules will be loaded.

command-line

While you can manage hostapd and dnsmasq IP forwarding, and Network Address Translation manually it is likely much easier to use the API that the Network Daemon netd provides either through the Android java framework via the NetworkManagementService class or via command-line with its command-line interface app netd.

For example, you can use netd to manage an Access Point with Linux NAT Routine (aka a 'Tethered Hotspot') using ncd:

  1. configure Access Point:
    ndc softap set wlan0 testssid broadcast 11 wpa-psk testpass # config hostapd
    
    • the softap set command has the usage: sotfap set <iface> <SSID> <hidden|broadcast> <channel> <wpa-psk|wpa2-psk|open> <passphrase>
      • /data/misc/wifi/hostapd.conf (which must be writable by netd) will be written to:
        interface=<iface>
        driver=nl80211
        ctrl_interface=/data/misc/wifi/hostapd
        ssid=testssid
        channel=<channel>
        ieee80211n=1
        hw_mode=g
        
      • for hidden an 'ignore_broadcast_ssid=1' will be added, for broadcast 'ignore_broadcast_ssid=0'
      • for wpa-psk 'wpa=1, wpa_pairwise=TKIP CCMD, wpa_psk' entries will be added
      • for wpa2-psk 'wpa=2, rsn_pairwise=CCMP, wpa_psk' entries will be added
  1. start the Access Point:
    ndc softap startap # start hostapd
    
    • Note that you can stop the Access Point at any time with ncd softap stopap
  1. configure the wlan0 interface:
    ndc interface setcfg wlan0 192.168.43.1 24 up
    
  1. configure tethering
    ndc tether interface add wlan0 # add wlan0 to tether
    ndc tether dns set 8.8.4.4 8.8.8.8 # add DNS servers
    ndc ipfwd enable # enable IP forwarding
    
  1. start tether of wlan0 with a specified DHCP pool (.10 to .99 in this case) (runs dnsmasq and configures NAT)
    ndc tether start 192.168.43.10 192.168.43.99
    
  1. start Network Address Translation (NAT)
    ndc nat enable wlan0 eth0 0
    

Note that when using Access Point mode, you must not enable Wireless from the Settings Application as this puts the radio in Client mode.


posted @ 2016-07-16 22:49  张同光  阅读(1031)  评论(0编辑  收藏  举报