NMAccessPoint * nm_ap_new_from_properties (GHashTable *properties) { NMAccessPoint *ap; GTimeVal cur_time; const struct ether_addr * addr; const char bad_bssid1[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const char bad_bssid2[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; g_return_val_if_fail (properties != NULL, NULL); ap = nm_ap_new (); g_object_freeze_notify (G_OBJECT (ap)); g_hash_table_foreach (properties, foreach_property_cb, ap); /* ignore APs with invalid BSSIDs */ addr = nm_ap_get_address (ap); if ( !(memcmp (addr->ether_addr_octet, bad_bssid1, ETH_ALEN)) || !(memcmp (addr->ether_addr_octet, bad_bssid2, ETH_ALEN))) { g_object_unref (ap); return NULL; } g_get_current_time (&cur_time); nm_ap_set_last_seen (ap, cur_time.tv_sec); if (!nm_ap_get_ssid (ap)) nm_ap_set_broadcast (ap, FALSE); g_object_thaw_notify (G_OBJECT (ap)); return ap; }
void nm_ap_update_from_properties (NMAccessPoint *ap, const char *supplicant_path, GVariant *properties) { NMAccessPointPrivate *priv; char *addr; const guint8 *bytes; GVariant *v; gsize len; gboolean b = FALSE; const char *s; gint16 i16; guint16 u16; g_return_if_fail (ap != NULL); g_return_if_fail (properties != NULL); priv = NM_AP_GET_PRIVATE (ap); g_object_freeze_notify (G_OBJECT (ap)); if (g_variant_lookup (properties, "Privacy", "b", &b) && b) nm_ap_set_flags (ap, priv->flags | NM_802_11_AP_FLAGS_PRIVACY); if (g_variant_lookup (properties, "Mode", "&s", &s)) { if (!g_strcmp0 (s, "infrastructure")) nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); else if (!g_strcmp0 (s, "ad-hoc")) nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); } if (g_variant_lookup (properties, "Signal", "n", &i16)) nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (i16)); if (g_variant_lookup (properties, "Frequency", "q", &u16)) nm_ap_set_freq (ap, u16); v = g_variant_lookup_value (properties, "SSID", G_VARIANT_TYPE_BYTESTRING); if (v) { bytes = g_variant_get_fixed_array (v, &len, 1); len = MIN (32, len); /* Stupid ieee80211 layer uses <hidden> */ if ( bytes && len && !(((len == 8) || (len == 9)) && !memcmp (bytes, "<hidden>", 8)) && !nm_utils_is_empty_ssid (bytes, len)) nm_ap_set_ssid (ap, bytes, len); g_variant_unref (v); } v = g_variant_lookup_value (properties, "BSSID", G_VARIANT_TYPE_BYTESTRING); if (v) { bytes = g_variant_get_fixed_array (v, &len, 1); if (len == ETH_ALEN) { addr = nm_utils_hwaddr_ntoa (bytes, len); nm_ap_set_address (ap, addr); g_free (addr); } g_variant_unref (v); } v = g_variant_lookup_value (properties, "Rates", G_VARIANT_TYPE ("au")); if (v) { const guint32 *rates = g_variant_get_fixed_array (v, &len, sizeof (guint32)); guint32 maxrate = 0; int i; /* Find the max AP rate */ for (i = 0; i < len; i++) { if (rates[i] > maxrate) { maxrate = rates[i]; nm_ap_set_max_bitrate (ap, rates[i] / 1000); } } g_variant_unref (v); } v = g_variant_lookup_value (properties, "WPA", G_VARIANT_TYPE_VARDICT); if (v) { nm_ap_set_wpa_flags (ap, priv->wpa_flags | security_from_vardict (v)); g_variant_unref (v); } v = g_variant_lookup_value (properties, "RSN", G_VARIANT_TYPE_VARDICT); if (v) { nm_ap_set_rsn_flags (ap, priv->rsn_flags | security_from_vardict (v)); g_variant_unref (v); } if (!priv->supplicant_path) priv->supplicant_path = g_strdup (supplicant_path); nm_ap_set_last_seen (ap, nm_utils_get_monotonic_timestamp_s ()); priv->fake = FALSE; g_object_thaw_notify (G_OBJECT (ap)); }