Wifi笔记 | Android P 启动流程之startSup
2020-01-12 本文已影响0人
力卉编程
一、WifiNative
WifiNative 主要工作:
- startHal
- startSupplicant
- createStaIface
这里主要讲第二点:startSupplicant
二、
2.1 startSupplicant
private boolean startSupplicant() {
synchronized (mLock) {
if (!mIfaceMgr.hasAnyStaIface()) {
if (!mWificondControl.enableSupplicant()) {
Log.e(TAG, "Failed to enable supplicant");
return false;
}
if (!waitForSupplicantConnection()) {
Log.e(TAG, "Failed to connect to supplicant");
return false;
}
if (!mSupplicantStaIfaceHal.registerDeathHandler(
new SupplicantDeathHandlerInternal())) {
Log.e(TAG, "Failed to register supplicant death handler");
return false;
}
}
return true;
}
}
private boolean waitForSupplicantConnection() {
// Start initialization if not already started.
if (!mSupplicantStaIfaceHal.isInitializationStarted()
&& !mSupplicantStaIfaceHal.initialize()) {
return false;
}
boolean connected = false;
int connectTries = 0;
while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
// Check if the initialization is complete.
connected = mSupplicantStaIfaceHal.isInitializationComplete();
if (connected) {
break;
}
try {
Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
} catch (InterruptedException ignore) {
}
}
return connected;
}
2.1 WificondControl::enableSupplicant
/**
* Enable wpa_supplicant via wificond.
* @return Returns true on success.
*/
public boolean enableSupplicant() {
if (!retrieveWificondAndRegisterForDeath()) {
return false;
}
try {
return mWificond.enableSupplicant();
} catch (RemoteException e) {
Log.e(TAG, "Failed to enable supplicant due to remote exception");
}
return false;
}
2.2 Server::enableSupplicant
//system/connectivity/wificond/server.cpp
Status Server::enableSupplicant(bool* success) {
*success = supplicant_manager_->StartSupplicant();
return Status::ok();
}
2.3 SupplicantManager::StartSupplicant()
启动的两行代码:
property_set("ctl.start", kSupplicantServiceName);
sched_yield(); //---这个应当是异步调用直接返回的意思
//frameworks/opt/net/wifi/libwifi_system/supplicant_manager.cpp
bool SupplicantManager::StartSupplicant() {
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 200; /* wait at most 20 seconds for completion */
const prop_info* pi;
unsigned serial = 0;
/* Check whether already running */
if (property_get(kSupplicantInitProperty, supp_status, NULL) &&
strcmp(supp_status, "running") == 0) {
return true;
}
/*
* Get a reference to the status property, so we can distinguish
* the case where it goes stopped => running => stopped (i.e.,
* it start up, but fails right away) from the case in which
* it starts in the stopped state and never manages to start
* running at all.
*/
pi = __system_property_find(kSupplicantInitProperty);
if (pi != NULL) {
serial = __system_property_serial(pi);
}
property_set("ctl.start", kSupplicantServiceName);
sched_yield();
while (count-- > 0) {
if (pi == NULL) {
pi = __system_property_find(kSupplicantInitProperty);
}
if (pi != NULL) {
/*
* property serial updated means that init process is scheduled
* after we sched_yield, further property status checking is based on this
*/
if (__system_property_serial(pi) != serial) {
__system_property_read(pi, NULL, supp_status);
if (strcmp(supp_status, "running") == 0) {
return true;
} else if (strcmp(supp_status, "stopped") == 0) {
return false;
}
}
}
usleep(100000);
}
return false;
}
2.4 总结
startSupplicant 是启动WIFI的协议栈登录认证接口,通过WificondControl::enableSupplicant调用Server::enableSupplicant,Server端启动了一个SupplicantManager来处理启动事件,最后调用
property_set("ctl.start", kSupplicantServiceName);
sched_yield();
通过 pi = __system_property_find(kSupplicantInitProperty);
来获取状态返回给上层等待函数:waitForSupplicantConnection。
这样就是一个完整的协议栈(startSupplicant)启动流程
完~~~
文 | 力卉编程