6.4.2 WifiStateMachine的处理

结合第5章对WifiService相关内容的介绍,假设当前STA没有连接上目标AP,则WifiStateMachine处于DisconnectedState。不过,DisconnectedState并不处理START_WPS消息,但其父状态ConnectedModeState会处理该消息,故直接来看ConnectedModeState的处理流程。

1.START_WPS处理流程分析

代码如下。

[—>WifiStateMachine.java::ConnectedModeState:processMessage]

  1. public boolean processMessage(Message message) {
  2. StateChangeResult stateChangeResult;
  3. switch(message.what) {
  4. ......
  5. case WifiManager.START_WPS:
  6. WpsInfo wpsInfo = (WpsInfo) message.obj;
  7. WpsResult result;
  8. switch (wpsInfo.setup) {
  9. case WpsInfo.PBC:
  10. result = mWifiConfigStore.startWpsPbc(wpsInfo);
  11. break;
  12. ......// WpsInfo.Keypad的处理
  13. case WpsInfo.DISPLAY:// 对PIN来说,setup的值为DISPLAY
  14. // 调用WifiConfigStore的startWpsWithPinFromDevice函数
  15. result = mWifiConfigStore.startWpsWithPinFromDevice(wpsInfo);
  16. break;
  17. default:
  18. result = new WpsResult(Status.FAILURE);
  19. break;
  20. }
  21. if (result.status == Status.SUCCESS) {
  22. // 回复WifiManager,界面框中将显示动态PIN码
  23. replyToMessage(message, WifiManager.START_WPS_SUCCEEDED, result);
  24. transitionTo(mWpsRunningState);// 转入WpsRunningState
  25. }
  26. ......// 错误处理
  27. break;
  28. ......
  29. }
  30. return HANDLED;
  31. }

来看startWpsWithPinFromDevice函数,代码如下所示。

[—>WifiConfigStore.java::startWpsWithPinFromDevice]

  1. WpsResult startWpsWithPinFromDevice(WpsInfo config) {
  2. WpsResult result = new WpsResult();
  3.  
  4.  
  5. /*
  6. config.BSSID代表目标AP的MAC地址,此处为空。下面的startWpsPinDisplay函数将发送
  7. “WPS_PIN any”命令给WPAS。WPAS将计算一个动态PIN码返回给用户。这个PIN码也就是
  8. 图6-2右图所示的PIN码。
  9. */
  10. result.pin = mWifiNative.startWpsPinDisplay(config.BSSID);
  11. if (!TextUtils.isEmpty(result.pin)) { // WPAS必须返回一个PIN码
  12. markAllNetworksDisabled(); // 停止使用其他网络
  13. result.status = WpsResult.Status.SUCCESS;
  14. } else
  15. result.status = WpsResult.Status.FAILURE;
  16. return result;
  17. }

当WPAS成功返回PIN码后,WifiStateMachine将从DisconnectedState状态进入WpsRunningState。该状态的enter函数没有做什么有意义的工作。

2.WPS_SUCCESS_EVENT处理流程分析

当WPAS完成WSC流程后,它将发送WPS-SUCCESS给WifiMonitor,而WifiMonitor将发送WPS_SUCCESS_EVENT给WifiStateMachine。该消息将由WpsRunningState状态处理,相关代码如下所示。

[—>WifiStateMachine.java::WpsRunningState:processMessage]

  1. public boolean processMessage(Message message) {
  2. switch (message.what) {
  3. case WifiMonitor.WPS_SUCCESS_EVENT: // 收到来自WPAS的WPS成功消息
  4. // 回复WifiManager。如此,WpsDialog中WpsListener对象的onCompleted函数将被调用
  5. replyToMessage(mSourceMessage, WifiManager.WPS_COMPLETED);
  6. mSourceMessage.recycle();
  7. mSourceMessage = null;
  8. transitionTo(mDisconnectedState);// 转入DisconnectedState
  9. break;
  10. ......
  11. }
  12. }

如果WSC流程一切顺利,WifiStateMachine将从WpsRunningState重新进入DisconnectedState。WifiStateMachine以后的流程就和5.3.2节所述的流程完全一样了。

提示 WifiStateMachine内部也会发起扫描请求,这和第5章分析的流程略有不同。第5章中,扫描请求由WifiSettings发起。

由上文介绍可知,Android App层以及Framework WifiService相关模块对WSC的处理非常简单。它们将通过发送"WPS_PIN any"命令以触发WPAS开始WSC的处理流程。下面分析WPAS中WSC的处理。