Wifi 连接部分
当用户选择一个AP时会弹出一个AP参数配置对话框,此对话框会显示当前选择的AP信号强度,若此AP设置了密码则需要用户输入密码才能登录。WifiSettings中的 onPreferenceTreeClick会被调用 @Override ic boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { //点击AP响应函数 if (preference instanceof AccessPoint) { mSelected = (AccessPoint) preference; showDialog(mSelected, false); } else if (preference == mAddNetwork) { mSelected = null; showDialog(null, true); } else if (preference == mNotifyOpenNetworks) { Secure.putInt(getContentResolver(), Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, mNotifyOpenNetworks.isChecked() ? 1 : 0); } else { return super.onPreferenceTreeClick(screen, preference); } return true; 用户配置好之后点击连接按钮,onClick函数会被调用。 public void onClick(DialogInterface dialogInterface, int button) { //点击连接按钮的响应函数 if (button == WifiDialog.BUTTON_FORGET && mSelected != null) { forget(mSelected.networkId); } else if (button == WifiDialog.BUTTON_SUBMIT && mDialog != null) { WifiConfiguration config = mDialog.getConfig(); if (config == null) { if (mSelected != null && !requireKeyStore(mSelected.getConfig())) { connect(mSelected.networkId); } } else if (config.networkId != -1) { if (mSelected != null) { mWifiManager.updateNetwork(config); saveNetworks(); } } else { int networkId = mWifiManager.addNetwork(config); if (networkId != -1) { mWifiManager.enableNetwork(networkId, false); config.networkId = networkId; if (mDialog.edit || requireKeyStore(config)) { saveNetworks(); } else { connect(networkId); } } } } 连接请求部分 一.Settings的connect函数响应连接,更新网络保存配置,更新设置当前选择的优先级最高,并保存。然后通过enableNetwork使得其他网络不可用来进行连接。最后调用WifiManager的reconnect函数连接当前选择的网络。 二.WifiManager的reconnect函数通过AIDL的Binder机制,调用WifiService的reconnect函数 三.然后会调用 WifiStateTracker的reconnectCommand函数,通过JNI(android_net_wifi_Wifi)的android_net_wifi_reconnectCommand 函数向WPA_WPASUPPLICANT发送 RECONNECT命令。 四. android_net_wifi_Wifi通过 doCommand(命令名,响应缓冲,响应缓存大小)调用wifi.c中的 wifi_command函数来发送命令。 五.最后通过 wpa_ctrl的wpa_ctrl_request函数向控制通道发送连接命令。 返回请求部分 六.当连接上之后WPA_SUPPLICANT会向控制通道发送连接成功命令。wifi.c的 wifi_wait_for_event函数阻塞调用并返回这个命令的字符串(CONNECTED). 七.而后WifiMonitor会被执行来处理这个事件,WifiMonitor 再调用 WifiStateTracker的notifyStateChange,WifiStateTracker 则接着会往自身发送 EVENT_DHCP_START 消息来启动DHCP 去获取 IP 地址,然后广播NETWORK_STATE_CHANGED_ACTION消息,最后由WifiSettings类来响应,改变状态和界面信息。 关键函数功能介绍 一.connect函数功能 1.updateNetwork:updateNetwork(config)会将当前选择连接的AP配置信息 信息传递进去,配置信息有(网络ID等)。如果网络ID为-1则重新添加网络配置,然后向wpa_supplicant 发送SET_NETWORK命令(即通过这个网络ID设置其他一些相关信息,设置SSID,密码等)如果网络配置不为-1则直接执行后面步骤即发送SET_NETWORK命令。 2.saveNetwork:告诉supplicant保存当前网络配置并更新列表。SaveNetwork会调用WifiService的saveConfiguration向wpa_supplicant发送SAVE_CONFIG命令保存当前网络配置信息,如果返回false,则向wpa_supplicant重新发送RECONFIGURE命令获取配置信息,如果获取信息成功后,会Intent一个 NETWORK_IDS_CHANGED_ACTION事件WifiSettings会注册接受这个 时间并更新列表。 3.enableNetwork函数,向系统获取接口名并使得该接口有效。由于之前传递的disableOthers为true则向wpa_supplicant发送SELECT_NETWORK(如果传递的为false则发送ENABLE_NETWORK命令), 4.reconnect函数:连接AP 二.reconnect函数功能:connect函数会调用WifiManager的reconnect然后通过Binder机制调用WifiService的reconnect,再由WifiStateTracke调用WifiNative向wpa_supplicant发送RECONNECT命令去连接网络,当连接上wpa_supplicant之后会向控制通道发送连接成功的命令,wifi_wait_for_event函数阻塞等待该事件的发生,并返回这个命令的字符串(CONNECTED) 三.android_net_wifi_Wifi函数的doCommand函数会调用wifi.c的wifi_command函数将上层的命令向wpa_supplicant发送。 四.wifi_wait_for_event函数以阻塞的方式,等待控制通道传递的事件。当有事件传递过来的时候该函数会通过wpa_ctrl的wpa_ctrl_recv函数读取该事件,并以字符串形式返回该事件名。 int wifi_wait_for_event(char *buf, size_t buflen) { ....... result = wpa_ctrl_recv(monitor_conn, buf, &nread); if (result < 0) { LOGD("wpa_ctrl_recv failed: %s/n", strerror(errno)); strncpy(buf, WPA_EVENT_TERMINATING " - recv error", buflen-1); buf[buflen-1] = '/0'; return strlen(buf); } buf[nread] = '/0'; /* LOGD("wait_for_event: result=%d nread=%d string=/"%s/"/n", result, nread, buf); */ /* Check for EOF on the socket */ if (result == 0 && nread == 0) { /* Fabricate an event to pass up */ LOGD("Received EOF on supplicant socket/n"); strncpy(buf, WPA_EVENT_TERMINATING " - signal 0 received", buflen-1); buf[buflen-1] = '/0'; return strlen(buf); } /* * Events strings are in the format * * 流程图对应的源代码路径为:
WifiEnabler,WifiSettings对应的路径如下: froyo/packages/apps/Settings/src/com/android/settings/ WifiManager,WifiMonitor,WifiStateTracker,WifiNative.对应的源代码路径如下:froyo/frameworrks/base/wifi/java/android/net/wifi/ WifiService 对应代码的位置froyo/frameworks/base/services/java/com/android/server/ android_net_wifi_Wifi源代码路径如下:froyo/frameworks/base/core/jni/ wifi_command,wifi_wait_for_envent源代码路径如下:/hardware/libhardware_legacy/wifi/wifi.c wpa_ctrl_源代码路径如下:/external/wpa_supplicant/wpa_ctrl.c wpa_supplicant源代码路径如下:froyo/external/wpa_supplicant/ |