本文介绍Android源码项目(AOSP)中WiFi功能的软件架构及各个模块(可执行文件、动态链接库)间的接口。
SDK API
Android SDK为开发者提供了WiFi编程接口,使用起来非常方便。
主要相关类:
WIFI编程入口,WIFI的多数功能都以该类的方法的形式提供
用于描述WIFI连接的状态
ScanResult
用于描述一个AP,如SSID,信号强度,安全方式等
下图基展示了Android系统WIFI模块的架构(当然,这只是软件的控制命令部分,数据部分直接通过kernel与网络子系统、socket API交互)
WifiManager是管理所有Wifi连接的基本API,可以通过以下调用得到它的实例:
android.content.Context.getSystemService(Context.WIFI_SERVICE)
具体 IPC(Inter-Process communication)
App & system_server(WifiManager & WifiService)
如果说Binder是连接 App 和 system_server 的桥梁,那么WifiManager和WiFiService就是桥梁的两头。
framework代码上和wifi相关的package位于:
frameworks/base/wifi/java(WIFI相关的一些包)
frameworks/base/services/java(各种Service,WIFI相关包为:com.android.server.wifi)
frameworks代码中,和wifi相关的几个类的关系如下:
WifiService继承自IWifiManager.Stub;
IWifiManager.Stub又继承自Binder,同时实现了IWifiManager接口;
WifiManager.Stu.proxy也实现了IWifiManager接口;
如图:
其中,IWifiManager, IWifiManager.Stub, IWifiManager.Stub.Proxy
都由IWifiManger.aidl
生成;
aidl自动生成相关的java代码,简化了用Binder实现RPC的过程。
IWifiManager.Stub.Proxy,WifiManager,BinberProxy用于客户端(App进程);
而IWifiManager.Stub,WifiService,Binder用于服务端(SystemServer进程)。
App 与 system_server 通过Binder通信,但Binder本身只实现了IPC,即类似socket通信的能力。而App端的WifiManager和system_server端的WifiService及Binder等类共同实现了RPC(remote procedure call)。
WifiManager只是系统为app提供的接口。Context.getSystemService(Context.WIFI_SERVICE)
返回的实际对象类型是IWifiManager.Stub.Proxy
。
IWifiManager.Stub.Proxy的实例是位于App端的一个代理,代理象IWifiManager.Stub.Proxy
将WifiManager方法的参数序列化到Parcel,再经Binder发送给system_server进程。
system_server内的WifiService收App传来的WifiManager调用,完成实际工作。
这样,实际和下层通信的工作就由App转移到了system_server进程(WifiService对象)。
WifiStateMachine
另外,可以看到 WifiStateMachine 是wifi功能的枢纽,几种不同模式下的控制流程都经它流下。
当WIFI处在STA模式(或P2P模式)时,通过WifiNative与wpa_supplicant交互。
WifiNative定义了几个Native方法:
public native static boolean setMaxTxPower(int txpower, boolean sapRunning);
public native static boolean loadDriver();
public native static boolean isDriverLoaded();
public native static boolean unloadDriver();
public native static boolean startSupplicant(boolean p2pSupported, int firstScanDelay);
/* Sends a kill signal to supplicant. To be used when we have lost connection
or when the supplicant is hung */
public native static boolean killSupplicant(boolean p2pSupported);
private native boolean connectToSupplicantNative();
private native void closeSupplicantConnectionNative();
/**
* Wait for the supplicant to send an event, returning the event string.
* @return the event string sent by the supplicant.
*/
private native String waitForEventNative();
private native boolean doBooleanCommandNative(String command);
private native int doIntCommandNative(String command);
private native String doStringCommandNative(String command);
当WIFI处在AP模式。通过NetworkManagementService与netd交互,具体是通过LocalSocket(Framework封装的UNIX域socket)与netd进程通信。
比如,NetworkManagementService.startAccessPoint方法:
@Override
public void startAccessPoint(
WifiConfiguration wifiConfig, String wlanIface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
wifiFirmwareReload(wlanIface, "AP");
if (wifiConfig == null) {
mConnector.execute("softap", "set", wlanIface); // 向 netd 发送控制命令
} else {
mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
wifiConfig.hiddenSSID ? "hidden" : "broadcast",
"1", getSecurityType(wifiConfig),
new SensitiveArg(wifiConfig.preSharedKey));
}
mConnector.execute("softap", "startap");
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
}
WifiNative
从功能上来说,WifiNative是system_server 和 wpa_supplicant 对话的窗口,实际上主要依靠wpa_supplicant项目编译出来的动态库libwpa_client.so。
WifiNative的几个native方法的具体实现在:
frameworks/base/core/jni/android_net_wifi_WifiNative.cpp
WifiNative的native方法的实现:
static JNINativeMethod gWifiMethods[] = {
/* name, signature, funcPtr */
{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
{ "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
{ "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
{ "startSupplicant", "(ZI)Z", (void *)android_net_wifi_startSupplicant },
{ "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
{ "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant },
{ "closeSupplicantConnectionNative", "()V", (void *)android_net_wifi_closeSupplicantConnection },
{ "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForE
原文链接:https://www.361shipin.com/blog/1545958076450865152