4.5.2 SET_NETWORK命令处理

最后更新于:2022-04-02 06:03:22

SET_NETWORK对应的命令处理函数为wpa_supplicant_ctrl_iface_set_network,其代码如 下所示。 **ctrl_iface.c::wpa_supplicant_ctrl_iface_set_network** ~~~ static int wpa_supplicant_ctrl_iface_set_network( struct wpa_supplicant *wpa_s, char *cmd) { int id; struct wpa_ssid *ssid; char *name, *value; // SET_NETWORK的参数是: " " name = os_strchr(cmd, ' '); *name++ = '\0'; // 获取name value = os_strchr(name, ' '); *value++ = '\0'; // 获取value id = atoi(cmd); // 获取id ...... // 从wpa_config中的无线网络配置列表中找到对应编号的无线网络配置项 ssid = wpa_config_get_network(wpa_s->conf, id); ...... /* 为该网络设置对应的配置值。wpa_config_set函数的具体实现与4.3.4节"wpa_supplicant_ init_iface分析之一"介绍的wpa_config_process_global函数类似,其内部也是通过定义 一些宏和数组来完成配置项的设置,不讨论其细节。就本例而言,当三个SET_NETWORK命令处理 完毕时,wpa_ssid的 ssid="Test"、key_mgmt=WPA_KEY_MGMT_PSK、passphrase="12345Test"。 注意:虽然在命令行中设置的是psk="12345Test",但实际上密码值将保存在passphrase变量中。 */ if (wpa_config_set(ssid, name, value, 0) < 0) {......} // 清空对应的PMKSA缓存信息。wpa_s->wpa指向一个wpa_sm对象 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); if (wpa_s->current_ssid == ssid || wpa_s->current_ssid == NULL) eapol_sm_invalidate_cached_session(wpa_s->eapol); if ((os_strcmp(name, "psk") == 0 && value[0] == '"' && ssid->ssid_len) || (os_strcmp(name, "ssid") == 0 && ssid->passphrase)) wpa_config_update_psk(ssid);// 将字符串形式的passphrase转成key,见下文介绍 else if (os_strcmp(name, "priority") == 0) wpa_config_update_prio_list(wpa_s->conf); return 0; } ~~~ 我们在3.3.7节的开头部分曾介绍过Key和Passphrase的区别。一般而言,Passphrase(也叫Password)表现为human-readable的字符串,而Key则一般是二进制或十六进制的数据。STA和AP交互的是Key,而用户设置的是Passphrase。所以上述代码中需要将Passphrase转换成Key, 这是通过wpa_config_update_psk函数来完成的。其代码如下所示。 **config.c::wpa_config_update_psk** ~~~ void wpa_config_update_psk(struct wpa_ssid *ssid) { #ifndef CONFIG_NO_PBKDF2 // 本例支持该宏,如果没有它的话,用户只能输入十六进制的Key // 对用户设置的psk和ssid进行hash计算,最终的结果作为真正的Pre-Shared Key pbkdf2_sha1(ssid->passphrase,(char *) ssid->ssid, ssid->ssid_len,4096,ssid->psk, PMK_LEN); ssid->psk_set = 1; #endif /* CONFIG_NO_PBKDF2 */ } ~~~ SET_NETWORK命令处理的介绍到此为止。下面来看最后一个关键命令ENABLE_NETWORK的处理流程。
';