Android Wi-Fi 支持中文SSID修改

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

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值