最近遇到一個wifi問題,同一個手機,由eng版本升級到user版本後,去打開wifi,wifi一直處於正在打開狀態,打開不了。打印log顯示以下錯誤:
E/WifiStateMachine( 452): Failed to start supplicant!
D/StateMachine( 452): handleMessage: X
D/StateMachine( 452): handleMessage: E msg.what=131073
D/StateMachine( 452): processMsg: DriverLoadedState
D/WifiStateMachine( 452): DriverLoadedState{ what=131073 when=-10s843ms arg1=2 }
D/StateMachine( 452): processMsg: DefaultState
D/WifiStateMachine( 452): DefaultState{ what=131073 when=-10s843ms arg1=2 }
D/StateMachine( 452): handleMessage: X
D/StateMachine( 452): handleMessage: E msg.what=131083
D/StateMachine( 452): processMsg: DriverLoadedState
D/WifiStateMachine( 452): DriverLoadedState{ what=131083 when=-10s843ms }
E/ ( 452): fopen failed: /dev/cpuctl/ux/tasks, Permission denied
I/ActivityThread( 1572): Pub com.google.android.music.athome: com.google.android.music.athome.AtHomeContentProvider
I/ActivityThread( 1572): Pub com.google.android.music.MusicContent: com.google.android.music.store.MusicContentProvider
I/MusicStore( 1572): Database version: 44
W/CommandListener( 128): Failed to retrieve HW addr for wlan0 (No such device)
E/WifiStateMachine( 452): Unable to change interface settings: java.lang.IllegalStateException: command '10 interface setcfg wlan0 0.0.0.0 0 down' failed with '400 10 Failed to set address (No such device)'
D/wpa_supplicant( 1611): wpa_supplicant v2.0-devel-4.1.2
D/wpa_supplicant( 1611): Add randomness: count=1 entropy=0
看到W/CommandListener( 128): Failed to retrieve HW addr for wlan0 (No such device)
錯誤,以爲是沒寫地址導致的,去about phone查看wifi地址,果然是不可用的,但是用QXDM讀wifi地址(NV項爲4678項),地址是有的,也就是說引起wifi開啓不了的原因還是因爲Failed to start supplicant!,導致讀取地址也是失敗的。
start pupplicant是由WifiStateMachine直接調用wifinative的startSupplicant方法來處理的,最後調到wifi,c的wifi_start_supplicant
int wifi_start_supplicant(int p2p_supported)
{
char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
int count = 200; /* wait at most 20 seconds for completion */
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
const prop_info *pi;
unsigned serial = 0, i;
char supp_rdy_status[PROPERTY_VALUE_MAX] = "";
const prop_info *rdy_pi = NULL;
int rdy_loop_count = 0;
#endif
if (p2p_supported) {
strcpy(supplicant_name, P2P_SUPPLICANT_NAME);
strcpy(supplicant_prop_name, P2P_PROP_NAME);
/* Ensure p2p config file is created */
if (ensure_config_file_exists(P2P_CONFIG_FILE) < 0) {
ALOGE("Failed to create a p2p config file");
return -1;
}
} else {
strcpy(supplicant_name, SUPPLICANT_NAME);
strcpy(supplicant_prop_name, SUPP_PROP_NAME);
}
/* Check whether already running */
if (property_get(supplicant_name, supp_status, NULL)
&& strcmp(supp_status, "running") == 0) {
return 0;
}
/* Before starting the daemon, make sure its config file exists */
if (ensure_config_file_exists(SUPP_CONFIG_FILE) < 0) {
ALOGE("Wi-Fi will not be enabled");
return -1;
}
if (ensure_entropy_file_exists() < 0) {
ALOGE("Wi-Fi entropy file was not created");
}
/* Clear out any stale socket files that might be left over. */
wifi_wpa_ctrl_cleanup();
/* Reset sockets used for exiting from hung state */
for (i=0; i<MAX_CONNS; i++) {
exit_sockets[i][0] = exit_sockets[i][1] = -1;
}
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
/*
* 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(supplicant_prop_name);
if (pi != NULL) {
serial = pi->serial;
}
#endif
property_get("wifi.interface", primary_iface, WIFI_TEST_INTERFACE);
property_set("ctl.start", supplicant_name);
sched_yield();
while (count-- > 0) {
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
if (pi == NULL) {
pi = __system_property_find(supplicant_prop_name);
}
if (pi != NULL) {
__system_property_read(pi, NULL, supp_status);
if (strcmp(supp_status, "running") == 0) {
for (rdy_loop_count = 0; rdy_loop_count < 15000/RDY_WAIT_MS;
rdy_loop_count ++) {
if (rdy_pi == NULL) {
rdy_pi = __system_property_find(SUPP_RDY_PROP_NAME);
} else {
__system_property_read(rdy_pi, NULL, supp_rdy_status);
if (strcmp(supp_rdy_status, "1") == 0)
{
return 0;
}
}
usleep (RDY_WAIT_MS * 1000);
}
return -1;
} else if (pi->serial != serial &&
strcmp(supp_status, "stopped") == 0) {
return -1;
}
}
#else
if (property_get(supplicant_prop_name, supp_status, NULL)) {
if (strcmp(supp_status, "running") == 0)
return 0;
}
#endif
usleep(100000);
}
return -1;
}
查看開不了wifi的手機,各種配置文件均正常。再往下分析好像也沒有什麼問題。
查看下一個錯誤信息:W/CommandListener( 128): Failed to retrieve HW addr for wlan0 (No such device)
網上搜索了下這個錯誤,竟然還是很多人遇到這樣的錯誤,有人建議
Check that you have the modules in /system/lib/module,說是這個文件下面多了兩個驅動文件,刪除就可以了,但是查看問題手機和正常手機的modules下面的文件是一樣的。更多的版本是
1:在刷rom之前刷boot.img
2:wipe
3:刷rom
問題手機是升級了軟件版本開不了的,按照上面這個所說,想到了先下載了一個能開啓的版本,然後一步步升級軟件版本,先寫了boot.img,然後是system.img,userdata.img,這幾個每次寫完都看一下wifi是否能打開,結果這三個都是正常的。接下來寫了persist.img,這個寫進去後,wifi開不了了。找到了是有這個persist,img引起的。之前調wifi參數時,曾經修改過手機裏persist/bdata.bin這個文件。然後看了下問題手機裏persist這個目錄下面沒有bdata.bin這個文件,push進去一個bdata.bin,wifi就能正常開啓,問題解決。
同一套代碼,編譯成eng版本,wifi是正常,編譯成user版本,persist目錄下就沒有了bdata.bin這個文件。查看makefile等信息,都沒有對版本編譯做限制的條件編譯,這個問題不知道是什麼原因。