1 Android平台中文SSID支持情况
使用Android设置作为热点,设置成中文SSID,Android设备可以扫描并连接上。但是使用路由器设置则不行。其原因是目前Android SSID获取时只处理了UTF-8的编码,对于非UTF-8,比如GBK编码,则未处理,最终导致有些中文SSID显示为乱码,而且连接不上。
2 具体修改说明
2.1 中文SSID显示乱码原因分析
在frameworks/base/wifi/java/android/net/wifi/WifiSsid.java的函数toString处理wpa_supplicant上报的ssid名字时只考虑了UTF-8编码。
@@ -168,7 +168,8 @@ public class WifiSsid implements Parcelable {
// behavior of returning empty string for this case.
if (octets.size() <= 0 || isArrayAllZeroes(ssidBytes)) return "";
// TODO: Handle conversion to other charsets upon failure
+ // 原来默认都当成UTF-8编码,导致GBK编码显示乱码。
- Charset charset = Charset.forName("UTF-8");
+ String charencode = EncodeType.encodeTest(ssidBytes, ssidBytes.length);
+ // 需要修改成自动识别编码方式
+ Charset charset = Charset.forName(charencode);
CharsetDecoder decoder = charset.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
这样子修改后,设置扫描列表中可以正常显示中文SSID了,但是连接不上。
2.2 中文SSID连接不上问题分析
2.2.1 SSID名字不匹配
在wpa_supplicant中去连接AP前,wpa_supplicant会先去作扫描,并在扫描到的AP中找要连接的AP,这里面有一系列的匹配参数,包括ssid名字,加密方式等(具体在wpa_scan_res_match函数中)。由于Android中将GBK编码的SSID转换成了UTF-8,并在连接过程中的SET_NETWORK中将UTF-8格式的SSID传给wpa_supplicant(这个SSID跟密码,加密方式等会保存在wpa_supplicant.conf文件中),这与扫描到的SSID(GBK编码)名字匹配不上,导致wpa_supplicant不会去连接。
@@ -718,6 +721,10 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
if (ssid->bssid_set && ssid->ssid_len == 0 &&
os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) == 0)
check_ssid = 0;+
+ // if ssid not ascii encode, skip ssid check // 如果SSID带有非asiic名字,则不去作SSID名字匹配,而采用BSSID
+ if(is_ascii_encode_wpa_ssid_txt(bss->ssid, bss->ssid_len) == 0)
+ check_ssid = 0;
现在的解决方法是:判断到非asiic编码的SSID时,不使用SSID去匹配,而使用BSSID(也就是路由器的MAC地址)去匹配。这样子修改后,针对未加密的中文SSID路由器,可以成功连接上,但是对于加密的中文SSID路由器,则连接失败,失败在4次握手过程中。
2.2.2 四次握手出错
四次握手过程中用到的psk是由SSID与passphrase(用户输入的wifi密码)组成的,由于SSID编码问题造成不计算出错误的psk,导致连接不上。
现在的解决方法是:在wpa_scan_res_match函数中查找要连接的匹配路由器时,将conf中的UTF-8编码的SSID替换成扫描到的GBK编码的SSID,并重新计算psk(使用函数wpa_config_update_psk)
if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
continue;
@@ -767,6 +774,19 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
int i, struct wpa_bss *bss,
struct wpa_ssid *group,
int only_first_ssid)
{
.......
if (!rate_match(wpa_s, bss)) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip - rate sets do "
"not match");
continue;
}
+
+ // if ssid do not same, use scan ssid, and redo wpa_config_update_psk
+ if (ssid->bssid_set && (bss->ssid_len != ssid->ssid_len ||
+ os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) {
+ //wpa_dbg(wpa_s, MSG_DEBUG, "---- before ssid='%s' ", wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
+ os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
+ ssid->ssid_len = bss->ssid_len; // 将conf中的UTF-8编码的SSID替换成扫描到的GBK编码的SSID,以便后面的成功连接
+ if(ssid->psk_set) {
+ ///wpa_dbg(wpa_s, MSG_DEBUG, "---- wpa_config_update_psk ----");
+ wpa_config_update_psk(ssid); // 重新利用正常的SSID名字计算PSK
+ }
+ //wpa_dbg(wpa_s, MSG_DEBUG, "---- after ssid='%s' ", wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
+ }
#ifdef CONFIG_P2P
.......
}
3 测试及存在的问题
3.1 存在的问题
3.1.1 中文SSID并隐藏SSID时连接不上
未找到原因,测试过mtk的机器也有类似问题。
3.2 Patch下载
整体代码修改下载路径
http://download.csdn.net/download/xiaoxiangyuhai/9954863