17、WiFi Passpoint(Hotspot 2.0):Passpoint简介、配置Passpoint凭据、自动连接Passpoint网络
各位同学,今天我们来聊聊WiFi领域一个非常实用的技术——Passpoint,也就是大家常说的Hotspot 2.0。说实话,这个技术刚出来的时候,我第一反应是:“这不就是让连WiFi更方便点吗?”后来在项目中真正落地才发现,它背后的设计思路远比我想象的巧妙。
17.1 Passpoint简介
Passpoint,说白了就是WiFi联盟搞的一套认证标准。它的核心目标是什么?让你像用蜂窝网络一样用WiFi——走到哪自动连上,不用每次都去翻找密码、点开网页登录。
我印象很深,有一次在机场,看到旁边一个人拿着手机疯狂刷登录页面,密码输了三次都不对。我当时就想,要是机场部署了Passpoint,他根本不用操这个心。
Passpoint的核心价值:
- 自动发现:设备能自动找到支持Passpoint的网络
- 自动认证:凭据匹配后自动完成认证,无需用户干预
- 无缝漫游:在不同AP之间切换时,连接不会断
- 安全加密:基于802.1X的EAP认证,比普通门户登录安全得多
你可能会问:“这和普通的WiFi有什么本质区别?”嗯,区别大了。普通WiFi你得知道SSID、密码,或者打开浏览器点“同意”。Passpoint呢?它用的是运营商或服务商下发的凭据,设备自动匹配网络,连上就完事。
我给大家画个图,看看Passpoint的架构长什么样:
从图上你能看到,整个流程其实不复杂。设备通过ANQP协议去查询AP的能力,AP告诉设备“我支持Passpoint”,然后设备拿出凭据去AAA服务器认证。认证通过,连接就建立了。
17.2 配置Passpoint凭据
配置凭据这块,我踩过不少坑。先说凭据的类型,主要有三种:
| 凭据类型 | 典型场景 | 安全等级 |
|---|---|---|
| SIM卡凭据 | 运营商部署的公共热点 | 高(基于USIM认证) |
| 用户名/密码 | 企业或校园网络 | 中(需配合EAP) |
| 数字证书 | 高安全要求的内部网络 | 极高(双向认证) |
我个人习惯在Android上配置时,优先用WifiManager的addPasspointConfiguration()方法。为什么?因为它能直接操作底层的Passpoint配置,比手动去设置里点来点去靠谱多了。
来看一段代码,这是配置用户名密码凭据的典型写法:
// 创建Passpoint配置
PasspointConfiguration config = new PasspointConfiguration();
// 设置FQDN(完全限定域名)
config.setFqdn("hotspot.example.com");
// 设置友好名称
config.setFriendlyName("Example Passpoint Network");
// 创建凭据对象
Credential credential = new Credential();
// 设置用户名密码
Credential.UserCredential userCred = new Credential.UserCredential();
userCred.setUsername("user@example.com");
userCred.setPassword("your_password");
userCred.setEapType(Eap.EAP_TTLS);
userCred.setNonEapInnerMethod("PAP");
credential.setUserCredential(userCred);
config.setCredential(credential);
// 添加到系统
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
int result = wifiManager.addPasspointConfiguration(config);
if (result == WifiManager.STATUS_SUCCESS) {
Log.d("Passpoint", "配置添加成功");
} else {
Log.e("Passpoint", "配置添加失败,错误码:" + result);
}
小提示:配置FQDN时一定要和服务器端保持一致。我曾经因为大小写问题折腾了半天——FQDN是区分大小写的,别问我怎么知道的。
如果是SIM卡凭据,代码会更简单一些。因为SIM卡的信息是直接从UICC里读的,你只需要指定EAP方法为EAP.SIM或EAP.AKA就行:
Credential.SimCredential simCred = new Credential.SimCredential();
simCred.setEapType(Eap.EAP_SIM);
simCred.setImsi("310150123456789"); // 可选,用于匹配
credential.setSimCredential(simCred);
config.setCredential(credential);
注意:SIM卡凭据需要设备支持UICC读取,并且运营商那边要开通相应的Passpoint服务。不是所有SIM卡都能用,别想当然。
17.3 自动连接Passpoint网络
配置好凭据之后,自动连接就是水到渠成的事了。Android系统会定期扫描周围的WiFi网络,当发现某个AP广播的Passpoint信息和你存储的凭据匹配时,就会自动发起连接。
这里有个关键点——匹配规则。系统是怎么判断“这个网络我能连”的?
- FQDN匹配:AP广播的FQDN和你配置的FQDN一致
- 运营商匹配:如果是SIM卡凭据,IMSI的前几位(MCC+MNC)要对得上
- Roaming Consortium OI匹配:AP广播的OI列表里包含你的凭据所属的OI
我记得有一次调试,明明凭据配置对了,但死活连不上。后来抓包一看,AP广播的OI列表里少了一个关键项。嗯,这种问题往往不是客户端的问题,是网络侧配置不全。
如果你想在代码里监听自动连接的状态,可以注册一个BroadcastReceiver:
BroadcastReceiver passpointReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.PASSPOINT_LAUNCH.equals(action)) {
// Passpoint网络被发现,即将发起连接
Log.d("Passpoint", "发现可用的Passpoint网络");
} else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (info != null && info.isConnected()) {
// 检查是否是通过Passpoint连接的
WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
if (wifiInfo != null && wifiInfo.isPasspointAp()) {
Log.d("Passpoint", "已自动连接到Passpoint网络: " + wifiInfo.getPasspointFqdn());
}
}
}
}
};
避坑指南:
我曾经遇到过一个情况——用户明明配置了Passpoint凭据,但到了热点区域就是连不上。排查了半天,发现是WiFi扫描间隔被系统省电策略拉长了。说白了,系统觉得“没必要频繁扫描”,结果错过了Passpoint网络的广播。
解决方案?在需要的时候主动触发一次扫描:
wifiManager.startScan();
或者提醒用户关闭省电模式。这个坑,我建议你们记一下。
自动连接的流程,说白了就是三步:
- 发现:设备扫描到AP,AP通过Beacon帧或Probe Response广播Passpoint能力
- 匹配:设备用ANQP协议查询AP的详细信息,和自己存储的凭据做比对
- 连接:匹配成功,发起EAP认证,建立安全连接
整个过程对用户来说是完全透明的。你走进咖啡厅,手机震一下,WiFi已经连上了。这才是Passpoint该有的体验。
最后说一句,Passpoint的调试其实挺麻烦的。因为涉及网络侧、设备侧、运营商三方的配合。我建议你在开发阶段,先用一台支持Passpoint的测试AP,配合Wireshark抓包看看ANQP的交互过程。看到ANQP Query和ANQP Response的报文正常交换,基本就成功了一半。
公众号:蓝海资料掘金营,微信deep3321