android wifi不能连接中文AP,分为不能连接中文AP和扫描结果不能显示中文AP。整体的思路就是需要将GBK的String转化为UTF8的字符串。具体现象如下,中文不会出现在supplicant的log中,会以转义字符的形式出现。
1
frameworks/opt/net/wifi/service/Android.mk
添加uc和i18n这两个库。
2 frameworks/opt/net/wifi/service/jni/android_net_wifi_Gbk2Utf.h/android_net_wifi_Gbk2Utf.cpp
不是将所有的字符转化为utf8,而是将出现SSID的地方由GBK转化为utf8。在android_net_wifi_Gbk2Utf.h中定义了
parseScanResults(String16& str, const char *reply); ----> BSS RANGE=
constructSsid(String16& str, const char *reply); ----> GET_NETWORK/ssid
constructEventSsid(char *eventstr); ----> SSID=/ SSID
setNetworkVariable(char *buf); ----> SET_NETWORK
其中只有constructEventSsid涉及到了SSID,其他三个完全没有出现SSID,应该是kk平台和L平台supplicant的log变化有关。
思考为什么以下方法不行。
3 frameworks/opt/net/wifi/service/jni/com_android_server_wifi_WifiNative.cpp
android_net_wifi_Gbk2Utf.h中定义的4个接口会在com_android_server_wifi_WifiNative.cpp中调用。
doCommand ----> doStringCommand ----> android_net_wifi_doStringCommand
android_net_wifi_waitForEvent
4
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConfigStore.java
去掉config.SSID前面的encodeSSID。
01-01 00:15:56.317 I/wpa_supplicant( 2377): p2p0: BSS: Add new id 0 BSSID 58:1f:28:69:ec:96 SSID '\xe7\xa7\xbb\xe5\x8a\xa8\xe7\x83\xad\xe7\x82\xb9xuhao'
01-01 00:15:56.319 D/WifiMonitor( 982): Event [IFNAME=p2p0 BSS: Add new id 0 BSSID 58:1f:28:69:ec:96 SSID '\xe7\xa7\xbb\xe5\x8a\xa8\xe7\x83\xad\xe7\x82\xb9xuhao']
01-01 00:17:18.106 D/WifiService( 982): Connect with config* ID: -1 SSID: "移动热点xuhao" BSSID: null FQDN: null REALM: null PRIO: 0
01-01 00:17:18.110 E/WifiStateMachine( 982): DisconnectedState !CONNECT_NETWORK uid=1000 -1 1 "移动热点xuhao"WPA_PSK any roam=0 rt=1524940
可以看到在supplicant及WifiMonitor中均显示转义字符,WifiSevice和WifiStateMachine中正常显示中文。在android L平台上要能支持中文AP。需要在以下3个地方添加代码。
1
frameworks/opt/net/wifi/service/Android.mk
添加uc和i18n这两个库。
LOCAL_C_INCLUDES += \
external/icu/icu4c/source/common \
external/icu/icu4c/source/i18n \
LOCAL_SHARED_LIBRARIES += \
libicuuc \
libicui18n
LOCAL_SRC_FILES := \
jni/com_android_server_wifi_WifiNative.cpp \
jni/android_net_wifi_Gbk2Utf.cpp \
2 frameworks/opt/net/wifi/service/jni/android_net_wifi_Gbk2Utf.h/android_net_wifi_Gbk2Utf.cpp
不是将所有的字符转化为utf8,而是将出现SSID的地方由GBK转化为utf8。在android_net_wifi_Gbk2Utf.h中定义了
parseScanResults(String16& str, const char *reply); ----> BSS RANGE=
95916:03-26 14:21:44.199 D/wpa_supplicant( 2263): wlan0: Control interface command 'BSS RANGE=0- MASK=0x21987'
constructSsid(String16& str, const char *reply); ----> GET_NETWORK/ssid
95916:03-26 14:21:44.199 D/wpa_supplicant( 2263): wlan0: Control interface command 'BSS RANGE=0- MASK=0x21987'
constructEventSsid(char *eventstr); ----> SSID=/ SSID
01-01 00:17:18.234 I/wpa_supplicant( 2377): selected BSS 58:1f:28:69:ec:96 ssid='\xe7\xa7\xbb\xe5\x8a\xa8\xe7\x83\xad\xe7\x82\xb9xuhao' freq=2462, rssi=-48
01-01 00:17:18.234 I/wpa_supplicant( 2377): wlan0: Trying to associate with SSID '\xe7\xa7\xbb\xe5\x8a\xa8\xe7\x83\xad\xe7\x82\xb9xuhao'
setNetworkVariable(char *buf); ----> SET_NETWORK
03-26 14:32:23.277 D/wpa_supplicant( 2263): wlan0: Control interface command 'SET_NETWORK [REMOVED]'
其中只有constructEventSsid涉及到了SSID,其他三个完全没有出现SSID,应该是kk平台和L平台supplicant的log变化有关。
思考为什么以下方法不行。
/*
* Convert string to Hexadecimal before passing to wifi native layer
* In native function "doCommand()" have trouble in converting Unicode character string to UTF8
* conversion to hex is required because SSIDs can have space characters in them;
* and that can confuses the supplicant because it uses space charaters as delimiters
*/
private String encodeSSID(String str){
String tmp = removeDoubleQuotes(str);
return String.format("%x", new BigInteger(1, tmp.getBytes(Charset.forName("UTF-8"))));
}
3 frameworks/opt/net/wifi/service/jni/com_android_server_wifi_WifiNative.cpp
android_net_wifi_Gbk2Utf.h中定义的4个接口会在com_android_server_wifi_WifiNative.cpp中调用。
doCommand ----> doStringCommand ----> android_net_wifi_doStringCommand
android_net_wifi_waitForEvent
4
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConfigStore.java
去掉config.SSID前面的encodeSSID。
mWifiNative.setNetworkVariable(
netId,
WifiConfiguration.ssidVarName,
encodeSSID(config.SSID))