mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 09:58:07 +02:00
Merge remote branch 'origin/new-supplicant'
This branch now requires wpa_supplicant 0.7 or later with the new D-Bus interface enabled. It also prefers the "nl80211" supplicant driver over the WEXT one, but will ask the supplicant to fall back to the WEXT driver if the device in question does not support the kernel's nl80211/cfg80211 stack.
This commit is contained in:
commit
a752140c8f
7 changed files with 566 additions and 708 deletions
|
|
@ -175,9 +175,6 @@ static void schedule_scan (NMDeviceWifi *self, gboolean backoff);
|
|||
|
||||
static void cancel_pending_scan (NMDeviceWifi *self);
|
||||
|
||||
static int wireless_qual_to_percent (const struct iw_quality *qual,
|
||||
const struct iw_quality *max_qual);
|
||||
|
||||
static void cleanup_association_attempt (NMDeviceWifi * self,
|
||||
gboolean disconnect);
|
||||
|
||||
|
|
@ -188,17 +185,13 @@ static void supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
|||
guint32 old_state,
|
||||
gpointer user_data);
|
||||
|
||||
static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
|
||||
GHashTable *properties,
|
||||
NMDeviceWifi * self);
|
||||
static void supplicant_iface_new_bss_cb (NMSupplicantInterface * iface,
|
||||
GHashTable *properties,
|
||||
NMDeviceWifi * self);
|
||||
|
||||
static void supplicant_iface_scan_request_result_cb (NMSupplicantInterface * iface,
|
||||
gboolean success,
|
||||
NMDeviceWifi * self);
|
||||
|
||||
static void supplicant_iface_scan_results_cb (NMSupplicantInterface * iface,
|
||||
guint32 num_bssids,
|
||||
NMDeviceWifi * self);
|
||||
static void supplicant_iface_scan_done_cb (NMSupplicantInterface * iface,
|
||||
gboolean success,
|
||||
NMDeviceWifi * self);
|
||||
|
||||
static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface,
|
||||
GParamSpec * pspec,
|
||||
|
|
@ -298,6 +291,107 @@ ipw_rfkill_state_work (gpointer user_data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* wireless_qual_to_percent
|
||||
*
|
||||
* Convert an iw_quality structure from SIOCGIWSTATS into a magical signal
|
||||
* strength percentage.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
wireless_qual_to_percent (const struct iw_quality *qual,
|
||||
const struct iw_quality *max_qual)
|
||||
{
|
||||
int percent = -1;
|
||||
int level_percent = -1;
|
||||
|
||||
g_return_val_if_fail (qual != NULL, -1);
|
||||
g_return_val_if_fail (max_qual != NULL, -1);
|
||||
|
||||
nm_log_dbg (LOGD_WIFI,
|
||||
"QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X",
|
||||
(__s8) qual->qual, qual->qual, qual->qual,
|
||||
(__s8) qual->level, qual->level, qual->level,
|
||||
(__s8) qual->noise, qual->noise, qual->noise,
|
||||
qual->updated,
|
||||
(__s8) max_qual->qual, max_qual->qual, max_qual->qual,
|
||||
(__s8) max_qual->level, max_qual->level, max_qual->level,
|
||||
(__s8) max_qual->noise, max_qual->noise, max_qual->noise,
|
||||
max_qual->updated);
|
||||
|
||||
/* Try using the card's idea of the signal quality first as long as it tells us what the max quality is.
|
||||
* Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be
|
||||
* bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers
|
||||
* are free to use whatever they want to calculate "Link Quality".
|
||||
*/
|
||||
if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID))
|
||||
percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual));
|
||||
|
||||
/* If the driver doesn't specify a complete and valid quality, we have two options:
|
||||
*
|
||||
* 1) dBm: driver must specify max_qual->level = 0, and have valid values for
|
||||
* qual->level and (qual->noise OR max_qual->noise)
|
||||
* 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for
|
||||
* qual->level and max_qual->level
|
||||
*
|
||||
* This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise,
|
||||
* If drivers don't conform to it, they are wrong and need to be fixed.
|
||||
*/
|
||||
|
||||
if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */
|
||||
&& !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */
|
||||
&& ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */
|
||||
|| ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */
|
||||
) {
|
||||
/* Absolute power values (dBm) */
|
||||
|
||||
/* Reasonable fallbacks for dumb drivers that don't specify either level. */
|
||||
#define FALLBACK_NOISE_FLOOR_DBM -90
|
||||
#define FALLBACK_SIGNAL_MAX_DBM -20
|
||||
int max_level = FALLBACK_SIGNAL_MAX_DBM;
|
||||
int noise = FALLBACK_NOISE_FLOOR_DBM;
|
||||
int level = qual->level - 0x100;
|
||||
|
||||
level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
|
||||
|
||||
if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))
|
||||
noise = qual->noise - 0x100;
|
||||
else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID))
|
||||
noise = max_qual->noise - 0x100;
|
||||
noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
|
||||
|
||||
/* A sort of signal-to-noise ratio calculation */
|
||||
level_percent = (int)(100 - 70 *(
|
||||
((double)max_level - (double)level) /
|
||||
((double)max_level - (double)noise)));
|
||||
nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.",
|
||||
level_percent, max_level, level, noise);
|
||||
} else if ( (max_qual->level != 0)
|
||||
&& !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */
|
||||
&& !(qual->updated & IW_QUAL_LEVEL_INVALID)) {
|
||||
/* Relative power values (RSSI) */
|
||||
|
||||
int level = qual->level;
|
||||
|
||||
/* Signal level is relavtive (0 -> max_qual->level) */
|
||||
level = CLAMP (level, 0, max_qual->level);
|
||||
level_percent = (int)(100 * ((double)level / (double)max_qual->level));
|
||||
nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.",
|
||||
level_percent, max_qual->level, level);
|
||||
} else if (percent == -1) {
|
||||
nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy.");
|
||||
}
|
||||
|
||||
/* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */
|
||||
if ((percent < 1) && (level_percent >= 0))
|
||||
percent = level_percent;
|
||||
|
||||
nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).",
|
||||
percent, CLAMP (percent, 0, 100));
|
||||
return (CLAMP (percent, 0, 100));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_wifi_update_signal_strength
|
||||
*
|
||||
|
|
@ -646,26 +740,20 @@ supplicant_interface_acquire (NMDeviceWifi *self)
|
|||
memset (priv->supplicant.sig_ids, 0, sizeof (priv->supplicant.sig_ids));
|
||||
|
||||
id = g_signal_connect (priv->supplicant.iface,
|
||||
"state",
|
||||
NM_SUPPLICANT_INTERFACE_STATE,
|
||||
G_CALLBACK (supplicant_iface_state_cb),
|
||||
self);
|
||||
priv->supplicant.sig_ids[i++] = id;
|
||||
|
||||
id = g_signal_connect (priv->supplicant.iface,
|
||||
"scanned-ap",
|
||||
G_CALLBACK (supplicant_iface_scanned_ap_cb),
|
||||
NM_SUPPLICANT_INTERFACE_NEW_BSS,
|
||||
G_CALLBACK (supplicant_iface_new_bss_cb),
|
||||
self);
|
||||
priv->supplicant.sig_ids[i++] = id;
|
||||
|
||||
id = g_signal_connect (priv->supplicant.iface,
|
||||
"scan-req-result",
|
||||
G_CALLBACK (supplicant_iface_scan_request_result_cb),
|
||||
self);
|
||||
priv->supplicant.sig_ids[i++] = id;
|
||||
|
||||
id = g_signal_connect (priv->supplicant.iface,
|
||||
"scan-results",
|
||||
G_CALLBACK (supplicant_iface_scan_results_cb),
|
||||
NM_SUPPLICANT_INTERFACE_SCAN_DONE,
|
||||
G_CALLBACK (supplicant_iface_scan_done_cb),
|
||||
self);
|
||||
priv->supplicant.sig_ids[i++] = id;
|
||||
|
||||
|
|
@ -1500,107 +1588,6 @@ nm_device_wifi_get_frequency (NMDeviceWifi *self)
|
|||
return freq;
|
||||
}
|
||||
|
||||
/*
|
||||
* wireless_stats_to_percent
|
||||
*
|
||||
* Convert an iw_stats structure from a scan or the card into
|
||||
* a magical signal strength percentage.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
wireless_qual_to_percent (const struct iw_quality *qual,
|
||||
const struct iw_quality *max_qual)
|
||||
{
|
||||
int percent = -1;
|
||||
int level_percent = -1;
|
||||
|
||||
g_return_val_if_fail (qual != NULL, -1);
|
||||
g_return_val_if_fail (max_qual != NULL, -1);
|
||||
|
||||
nm_log_dbg (LOGD_WIFI,
|
||||
"QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X",
|
||||
(__s8) qual->qual, qual->qual, qual->qual,
|
||||
(__s8) qual->level, qual->level, qual->level,
|
||||
(__s8) qual->noise, qual->noise, qual->noise,
|
||||
qual->updated,
|
||||
(__s8) max_qual->qual, max_qual->qual, max_qual->qual,
|
||||
(__s8) max_qual->level, max_qual->level, max_qual->level,
|
||||
(__s8) max_qual->noise, max_qual->noise, max_qual->noise,
|
||||
max_qual->updated);
|
||||
|
||||
/* Try using the card's idea of the signal quality first as long as it tells us what the max quality is.
|
||||
* Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be
|
||||
* bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers
|
||||
* are free to use whatever they want to calculate "Link Quality".
|
||||
*/
|
||||
if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID))
|
||||
percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual));
|
||||
|
||||
/* If the driver doesn't specify a complete and valid quality, we have two options:
|
||||
*
|
||||
* 1) dBm: driver must specify max_qual->level = 0, and have valid values for
|
||||
* qual->level and (qual->noise OR max_qual->noise)
|
||||
* 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for
|
||||
* qual->level and max_qual->level
|
||||
*
|
||||
* This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise,
|
||||
* If drivers don't conform to it, they are wrong and need to be fixed.
|
||||
*/
|
||||
|
||||
if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */
|
||||
&& !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */
|
||||
&& ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */
|
||||
|| ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */
|
||||
) {
|
||||
/* Absolute power values (dBm) */
|
||||
|
||||
/* Reasonable fallbacks for dumb drivers that don't specify either level. */
|
||||
#define FALLBACK_NOISE_FLOOR_DBM -90
|
||||
#define FALLBACK_SIGNAL_MAX_DBM -20
|
||||
int max_level = FALLBACK_SIGNAL_MAX_DBM;
|
||||
int noise = FALLBACK_NOISE_FLOOR_DBM;
|
||||
int level = qual->level - 0x100;
|
||||
|
||||
level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
|
||||
|
||||
if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))
|
||||
noise = qual->noise - 0x100;
|
||||
else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID))
|
||||
noise = max_qual->noise - 0x100;
|
||||
noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
|
||||
|
||||
/* A sort of signal-to-noise ratio calculation */
|
||||
level_percent = (int)(100 - 70 *(
|
||||
((double)max_level - (double)level) /
|
||||
((double)max_level - (double)noise)));
|
||||
nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.",
|
||||
level_percent, max_level, level, noise);
|
||||
} else if ( (max_qual->level != 0)
|
||||
&& !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */
|
||||
&& !(qual->updated & IW_QUAL_LEVEL_INVALID)) {
|
||||
/* Relative power values (RSSI) */
|
||||
|
||||
int level = qual->level;
|
||||
|
||||
/* Signal level is relavtive (0 -> max_qual->level) */
|
||||
level = CLAMP (level, 0, max_qual->level);
|
||||
level_percent = (int)(100 * ((double)level / (double)max_qual->level));
|
||||
nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.",
|
||||
level_percent, max_qual->level, level);
|
||||
} else if (percent == -1) {
|
||||
nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy.");
|
||||
}
|
||||
|
||||
/* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */
|
||||
if ((percent < 1) && (level_percent >= 0))
|
||||
percent = level_percent;
|
||||
|
||||
nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).",
|
||||
percent, CLAMP (percent, 0, 100));
|
||||
return (CLAMP (percent, 0, 100));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_wifi_get_ssid
|
||||
*
|
||||
|
|
@ -1910,28 +1897,19 @@ cancel_pending_scan (NMDeviceWifi *self)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
supplicant_iface_scan_request_result_cb (NMSupplicantInterface *iface,
|
||||
gboolean success,
|
||||
NMDeviceWifi *self)
|
||||
supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
|
||||
gboolean success,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan request %s",
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan %s",
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
success ? "successful" : "failed");
|
||||
|
||||
if (check_scanning_allowed (self))
|
||||
schedule_scan (self, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_scan_results_cb (NMSupplicantInterface *iface,
|
||||
guint32 num_results,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan results available (%d APs found)",
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
num_results);
|
||||
#if 0
|
||||
if (num_results == 0) {
|
||||
/* ensure that old APs get culled, which otherwise only
|
||||
* happens when there are actual scan results to process.
|
||||
|
|
@ -1939,6 +1917,7 @@ supplicant_iface_scan_results_cb (NMSupplicantInterface *iface,
|
|||
cull_scan_list (self);
|
||||
nm_device_wifi_ap_list_print (self);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -2158,48 +2137,10 @@ cull_scan_list (NMDeviceWifi *self)
|
|||
removed, total);
|
||||
}
|
||||
|
||||
#define SET_QUALITY_MEMBER(qual_item, lc_member, uc_member) \
|
||||
if (lc_member != -1) { \
|
||||
qual_item.lc_member = lc_member; \
|
||||
qual_item.updated |= IW_QUAL_##uc_member##_UPDATED; \
|
||||
} else { \
|
||||
qual_item.updated |= IW_QUAL_##uc_member##_INVALID; \
|
||||
}
|
||||
|
||||
static void
|
||||
set_ap_strength_from_properties (NMDeviceWifi *self,
|
||||
NMAccessPoint *ap,
|
||||
GHashTable *properties)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
int qual, level, noise;
|
||||
struct iw_quality quality;
|
||||
GValue *value;
|
||||
gint8 strength;
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (properties, "quality");
|
||||
qual = value ? g_value_get_int (value) : -1;
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (properties, "level");
|
||||
level = value ? g_value_get_int (value) : -1;
|
||||
|
||||
value = (GValue *) g_hash_table_lookup (properties, "noise");
|
||||
noise = value ? g_value_get_int (value) : -1;
|
||||
|
||||
/* Calculate and set the AP's signal quality */
|
||||
memset (&quality, 0, sizeof (struct iw_quality));
|
||||
SET_QUALITY_MEMBER (quality, qual, QUAL);
|
||||
SET_QUALITY_MEMBER (quality, level, LEVEL);
|
||||
SET_QUALITY_MEMBER (quality, noise, NOISE);
|
||||
|
||||
strength = wireless_qual_to_percent (&quality, &priv->max_qual);
|
||||
nm_ap_set_strength (ap, strength);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_scanned_ap_cb (NMSupplicantInterface *iface,
|
||||
GHashTable *properties,
|
||||
NMDeviceWifi *self)
|
||||
supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
|
||||
GHashTable *properties,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceState state;
|
||||
NMAccessPoint *ap;
|
||||
|
|
@ -2215,8 +2156,6 @@ supplicant_iface_scanned_ap_cb (NMSupplicantInterface *iface,
|
|||
|
||||
ap = nm_ap_new_from_properties (properties);
|
||||
if (ap) {
|
||||
set_ap_strength_from_properties (self, ap, properties);
|
||||
|
||||
nm_ap_print_self (ap, "AP: ");
|
||||
|
||||
/* Add the AP to the device's AP list */
|
||||
|
|
@ -3075,7 +3014,7 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
|
||||
/* Hook up error signal handler to capture association errors */
|
||||
id = g_signal_connect (priv->supplicant.iface,
|
||||
"connection-error",
|
||||
NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR,
|
||||
G_CALLBACK (supplicant_iface_connection_error_cb),
|
||||
self);
|
||||
priv->supplicant.iface_error_id = id;
|
||||
|
|
@ -3535,12 +3474,11 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled)
|
|||
/* Wait for some drivers like ipw3945 to come back to life */
|
||||
success = wireless_get_range (self, &range, NULL);
|
||||
|
||||
/* iface should be NULL here, but handle it anyway if it's not */
|
||||
g_warn_if_fail (priv->supplicant.iface == NULL);
|
||||
/* Re-initialize the supplicant interface and wait for it to be ready */
|
||||
if (priv->supplicant.iface)
|
||||
supplicant_interface_release (self);
|
||||
|
||||
supplicant_interface_acquire (self);
|
||||
|
||||
nm_log_dbg (LOGD_WIFI, "(%s): enable waiting on supplicant state",
|
||||
nm_device_get_iface (NM_DEVICE (device)));
|
||||
} else {
|
||||
|
|
|
|||
183
src/nm-wifi-ap.c
183
src/nm-wifi-ap.c
|
|
@ -22,6 +22,7 @@
|
|||
#include "wireless-helper.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nm-wifi-ap.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
|
@ -369,10 +370,69 @@ NMAccessPoint *nm_ap_new (void)
|
|||
return (NMAccessPoint *) object;
|
||||
}
|
||||
|
||||
static guint32
|
||||
pair_to_flags (const char *str)
|
||||
{
|
||||
g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
|
||||
|
||||
#define IEEE80211_CAP_ESS 0x0001
|
||||
#define IEEE80211_CAP_IBSS 0x0002
|
||||
#define IEEE80211_CAP_PRIVACY 0x0010
|
||||
if (strcmp (str, "wep40") == 0)
|
||||
return NM_802_11_AP_SEC_PAIR_WEP40;
|
||||
if (strcmp (str, "wep104") == 0)
|
||||
return NM_802_11_AP_SEC_PAIR_WEP104;
|
||||
if (strcmp (str, "tkip") == 0)
|
||||
return NM_802_11_AP_SEC_PAIR_TKIP;
|
||||
if (strcmp (str, "ccmp") == 0)
|
||||
return NM_802_11_AP_SEC_PAIR_CCMP;
|
||||
return NM_802_11_AP_SEC_NONE;
|
||||
}
|
||||
|
||||
static guint32
|
||||
group_to_flags (const char *str)
|
||||
{
|
||||
g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
|
||||
|
||||
if (strcmp (str, "wep40") == 0)
|
||||
return NM_802_11_AP_SEC_GROUP_WEP40;
|
||||
if (strcmp (str, "wep104") == 0)
|
||||
return NM_802_11_AP_SEC_GROUP_WEP104;
|
||||
if (strcmp (str, "tkip") == 0)
|
||||
return NM_802_11_AP_SEC_GROUP_TKIP;
|
||||
if (strcmp (str, "ccmp") == 0)
|
||||
return NM_802_11_AP_SEC_GROUP_CCMP;
|
||||
return NM_802_11_AP_SEC_NONE;
|
||||
}
|
||||
|
||||
static guint32
|
||||
security_from_dict (GHashTable *security)
|
||||
{
|
||||
GValue *value;
|
||||
guint32 flags = NM_802_11_AP_SEC_NONE;
|
||||
const char **items, **iter;
|
||||
|
||||
value = g_hash_table_lookup (security, "KeyMgmt");
|
||||
if (value) {
|
||||
items = g_value_get_boxed (value);
|
||||
for (iter = items; iter && *iter; iter++) {
|
||||
if (strcmp (*iter, "wpa-psk") == 0)
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
|
||||
else if (strcmp (*iter, "wpa-eap") == 0)
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
|
||||
}
|
||||
}
|
||||
|
||||
value = g_hash_table_lookup (security, "Pairwise");
|
||||
if (value) {
|
||||
items = g_value_get_boxed (value);
|
||||
for (iter = items; iter && *iter; iter++)
|
||||
flags |= pair_to_flags (*iter);
|
||||
}
|
||||
|
||||
value = g_hash_table_lookup (security, "Group");
|
||||
if (value)
|
||||
flags |= group_to_flags (g_value_get_string (value));
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void
|
||||
foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
|
||||
|
|
@ -383,9 +443,9 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
|
|||
if (G_VALUE_HOLDS_BOXED (variant)) {
|
||||
GArray *array = g_value_get_boxed (variant);
|
||||
|
||||
if (!strcmp (key, "ssid")) {
|
||||
if (!strcmp (key, "SSID")) {
|
||||
guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len);
|
||||
GByteArray * ssid;
|
||||
GByteArray *ssid;
|
||||
|
||||
/* Stupid ieee80211 layer uses <hidden> */
|
||||
if (((len == 8) || (len == 9))
|
||||
|
|
@ -399,7 +459,7 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
|
|||
g_byte_array_append (ssid, (const guint8 *) array->data, len);
|
||||
nm_ap_set_ssid (ap, ssid);
|
||||
g_byte_array_free (ssid, TRUE);
|
||||
} else if (!strcmp (key, "bssid")) {
|
||||
} else if (!strcmp (key, "BSSID")) {
|
||||
struct ether_addr addr;
|
||||
|
||||
if (array->len != ETH_ALEN)
|
||||
|
|
@ -407,43 +467,62 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
|
|||
memset (&addr, 0, sizeof (struct ether_addr));
|
||||
memcpy (&addr, array->data, ETH_ALEN);
|
||||
nm_ap_set_address (ap, &addr);
|
||||
} else if (!strcmp (key, "wpaie")) {
|
||||
guint8 * ie = (guint8 *) array->data;
|
||||
} else if (!strcmp (key, "Rates")) {
|
||||
guint32 maxrate = 0;
|
||||
int i;
|
||||
|
||||
/* Find the max AP rate */
|
||||
for (i = 0; i < array->len; i++) {
|
||||
guint32 r = g_array_index (array, guint32, i);
|
||||
|
||||
if (r > maxrate) {
|
||||
maxrate = r;
|
||||
nm_ap_set_max_bitrate (ap, r / 1000);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp (key, "WPA")) {
|
||||
guint32 flags = nm_ap_get_wpa_flags (ap);
|
||||
|
||||
if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
|
||||
return;
|
||||
flags = nm_ap_add_security_from_ie (flags, ie, array->len);
|
||||
flags |= security_from_dict (g_value_get_boxed (variant));
|
||||
nm_ap_set_wpa_flags (ap, flags);
|
||||
} else if (!strcmp (key, "rsnie")) {
|
||||
guint8 * ie = (guint8 *) array->data;
|
||||
} else if (!strcmp (key, "RSN")) {
|
||||
guint32 flags = nm_ap_get_rsn_flags (ap);
|
||||
|
||||
if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
|
||||
return;
|
||||
flags = nm_ap_add_security_from_ie (flags, ie, array->len);
|
||||
flags |= security_from_dict (g_value_get_boxed (variant));
|
||||
nm_ap_set_rsn_flags (ap, flags);
|
||||
}
|
||||
} else if (G_VALUE_HOLDS_INT (variant)) {
|
||||
gint32 int_val = g_value_get_int (variant);
|
||||
|
||||
if (!strcmp (key, "frequency")) {
|
||||
nm_ap_set_freq (ap, (guint32) int_val);
|
||||
} else if (!strcmp (key, "maxrate")) {
|
||||
/* Supplicant reports as b/s, we use Kb/s internally */
|
||||
nm_ap_set_max_bitrate (ap, int_val / 1000);
|
||||
}
|
||||
} else if (G_VALUE_HOLDS_UINT (variant)) {
|
||||
guint32 val = g_value_get_uint (variant);
|
||||
|
||||
if (!strcmp (key, "capabilities")) {
|
||||
if (val & IEEE80211_CAP_ESS) {
|
||||
nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
|
||||
} else if (val & IEEE80211_CAP_IBSS) {
|
||||
nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
|
||||
}
|
||||
if (!strcmp (key, "Frequency"))
|
||||
nm_ap_set_freq (ap, val);
|
||||
} else if (G_VALUE_HOLDS_INT (variant)) {
|
||||
gint val = g_value_get_int (variant);
|
||||
|
||||
if (val & IEEE80211_CAP_PRIVACY) {
|
||||
if (!strcmp (key, "Signal")) {
|
||||
if (val < 0) {
|
||||
/* Rough conversion: best = -40, worst = -100 */
|
||||
val = abs (CLAMP (val, -100, -40) + 40);
|
||||
val = 100 - (int) ((100.0 * (double) val) / 60.0);
|
||||
} else
|
||||
val /= 100;
|
||||
|
||||
nm_ap_set_strength (ap, val);
|
||||
}
|
||||
} else if (G_VALUE_HOLDS_STRING (variant)) {
|
||||
const char *val = g_value_get_string (variant);
|
||||
|
||||
if (val && !strcmp (key, "Mode")) {
|
||||
if (strcmp (val, "infrastructure") == 0)
|
||||
nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
|
||||
else if (strcmp (val, "ad-hoc") == 0)
|
||||
nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
|
||||
}
|
||||
} else if (G_VALUE_HOLDS_BOOLEAN (variant)) {
|
||||
gboolean val = g_value_get_boolean (variant);
|
||||
|
||||
if (strcmp (key, "Privacy") == 0) {
|
||||
if (val) {
|
||||
guint32 flags = nm_ap_get_flags (ap);
|
||||
nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY);
|
||||
}
|
||||
|
|
@ -451,7 +530,6 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
NMAccessPoint *
|
||||
nm_ap_new_from_properties (GHashTable *properties)
|
||||
{
|
||||
|
|
@ -1170,45 +1248,6 @@ void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list)
|
|||
}
|
||||
|
||||
|
||||
guint32
|
||||
nm_ap_add_security_from_ie (guint32 flags,
|
||||
const guint8 *wpa_ie,
|
||||
guint32 length)
|
||||
{
|
||||
wpa_ie_data * cap_data;
|
||||
|
||||
if (!(cap_data = wpa_parse_wpa_ie (wpa_ie, length)))
|
||||
return NM_802_11_AP_SEC_NONE;
|
||||
|
||||
/* Pairwise cipher flags */
|
||||
if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP40)
|
||||
flags |= NM_802_11_AP_SEC_PAIR_WEP40;
|
||||
if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP104)
|
||||
flags |= NM_802_11_AP_SEC_PAIR_WEP104;
|
||||
if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_TKIP)
|
||||
flags |= NM_802_11_AP_SEC_PAIR_TKIP;
|
||||
if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_CCMP)
|
||||
flags |= NM_802_11_AP_SEC_PAIR_CCMP;
|
||||
|
||||
/* Group cipher flags */
|
||||
if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP40)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_WEP40;
|
||||
if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP104)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_WEP104;
|
||||
if (cap_data->group_cipher & IW_AUTH_CIPHER_TKIP)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_TKIP;
|
||||
if (cap_data->group_cipher & IW_AUTH_CIPHER_CCMP)
|
||||
flags |= NM_802_11_AP_SEC_GROUP_CCMP;
|
||||
|
||||
if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_802_1X)
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
|
||||
if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_PSK)
|
||||
flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
|
||||
|
||||
g_slice_free (wpa_ie_data, cap_data);
|
||||
return flags;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ap_check_compatible (NMAccessPoint *self,
|
||||
NMConnection *connection)
|
||||
|
|
|
|||
|
|
@ -110,10 +110,6 @@ void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created);
|
|||
GSList * nm_ap_get_user_addresses (const NMAccessPoint *ap);
|
||||
void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list);
|
||||
|
||||
guint32 nm_ap_add_security_from_ie (guint32 flags,
|
||||
const guint8 *wpa_ie,
|
||||
guint32 length);
|
||||
|
||||
gboolean nm_ap_check_compatible (NMAccessPoint *self,
|
||||
NMConnection *connection);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -53,6 +53,12 @@ enum {
|
|||
#define NM_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_INTERFACE))
|
||||
#define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass))
|
||||
|
||||
#define NM_SUPPLICANT_INTERFACE_STATE "state"
|
||||
#define NM_SUPPLICANT_INTERFACE_REMOVED "removed"
|
||||
#define NM_SUPPLICANT_INTERFACE_NEW_BSS "new-bss"
|
||||
#define NM_SUPPLICANT_INTERFACE_SCAN_DONE "scan-done"
|
||||
#define NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR "connection-error"
|
||||
|
||||
struct _NMSupplicantInterface {
|
||||
GObject parent;
|
||||
};
|
||||
|
|
@ -70,18 +76,14 @@ typedef struct {
|
|||
/* interface was removed by the supplicant */
|
||||
void (*removed) (NMSupplicantInterface * iface);
|
||||
|
||||
/* interface saw a new access point from a scan */
|
||||
void (*scanned_ap) (NMSupplicantInterface * iface,
|
||||
DBusMessage * message);
|
||||
/* interface saw a new BSS */
|
||||
void (*new_bss) (NMSupplicantInterface *iface,
|
||||
GHashTable *props);
|
||||
|
||||
/* result of a wireless scan request */
|
||||
void (*scan_req_result) (NMSupplicantInterface * iface,
|
||||
/* wireless scan is done */
|
||||
void (*scan_done) (NMSupplicantInterface *iface,
|
||||
gboolean success);
|
||||
|
||||
/* scan results returned from supplicant */
|
||||
void (*scan_results) (NMSupplicantInterface * iface,
|
||||
guint num_bssids);
|
||||
|
||||
/* an error occurred during a connection request */
|
||||
void (*connection_error) (NMSupplicantInterface * iface,
|
||||
const char * name,
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ nm_supplicant_manager_iface_release (NMSupplicantManager *self,
|
|||
/* Ask wpa_supplicant to remove this interface */
|
||||
op = nm_supplicant_interface_get_object_path (iface);
|
||||
if (priv->running && priv->proxy && op) {
|
||||
dbus_g_proxy_call_no_reply (priv->proxy, "removeInterface",
|
||||
dbus_g_proxy_call_no_reply (priv->proxy, "RemoveInterface",
|
||||
DBUS_TYPE_G_OBJECT_PATH, op,
|
||||
G_TYPE_INVALID);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@
|
|||
#include "nm-supplicant-types.h"
|
||||
#include "nm-device.h"
|
||||
|
||||
#define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant"
|
||||
#define WPAS_DBUS_PATH "/fi/epitest/hostap/WPASupplicant"
|
||||
#define WPAS_DBUS_INTERFACE "fi.epitest.hostap.WPASupplicant"
|
||||
#define WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1"
|
||||
#define WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1"
|
||||
#define WPAS_DBUS_INTERFACE "fi.w1.wpa_supplicant1"
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue