wifi: indicate 2ghz and 5ghz wifi device capabilities
authorBeniamino Galvani <bgalvani@redhat.com>
Wed, 18 Mar 2015 20:56:51 +0000 (21:56 +0100)
committerBeniamino Galvani <bgalvani@redhat.com>
Wed, 8 Apr 2015 08:48:38 +0000 (10:48 +0200)
Add new capabilities CAP_FREQ_2GHZ and CAP_FREQ_5GHZ to indicate the
frequency bands supported by a Wifi device.

Add also CAP_FREQ_VALID, which is set when the values of the other 2
capabilities are available.

Original patch by Dan Williams <dcbw@redhat.com>

https://bugzilla.gnome.org/show_bug.cgi?id=723295

clients/cli/devices.c
introspection/nm-device-wifi.xml
libnm-core/nm-dbus-interface.h
libnm-util/NetworkManager.h
src/platform/wifi/wifi-utils-nl80211.c
src/platform/wifi/wifi-utils-wext.c
src/platform/wifi/wifi-utils.h

index 987d8de..36d9c2f 100644 (file)
@@ -122,9 +122,11 @@ static NmcOutputField nmc_fields_dev_show_wifi_prop[] = {
        {"CCMP",       N_("CCMP"),    6},  /* 5 */
        {"AP",         N_("AP"),      6},  /* 6 */
        {"ADHOC",      N_("ADHOC"),   6},  /* 7 */
+       {"2GHZ",       N_("2GHZ"),   10},  /* 8 */
+       {"5GHZ",       N_("5GHZ"),   10},  /* 9 */
        {NULL,         NULL,          0}
 };
-#define NMC_FIELDS_DEV_SHOW_WIFI_PROP_ALL     "NAME,WEP,WPA,WPA2,TKIP,CCMP,AP,ADHOC"
+#define NMC_FIELDS_DEV_SHOW_WIFI_PROP_ALL     "NAME,WEP,WPA,WPA2,TKIP,CCMP,AP,ADHOC,2GHZ,5GHZ"
 #define NMC_FIELDS_DEV_SHOW_WIFI_PROP_COMMON  "NAME,WEP,WPA,WPA2,TKIP,CCMP,AP,ADHOC"
 
 /* Available fields for 'device show' - wimax properties part */
@@ -979,6 +981,10 @@ show_device_info (NMDevice *device, NmCli *nmc)
                                set_val_strc (arr, 5, (wcaps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) ? _("yes") : _("no"));
                                set_val_strc (arr, 6, (wcaps & NM_WIFI_DEVICE_CAP_AP) ? _("yes") : _("no"));
                                set_val_strc (arr, 7, (wcaps & NM_WIFI_DEVICE_CAP_ADHOC) ? _("yes") : _("no"));
+                               set_val_strc (arr, 8, !(wcaps & NM_WIFI_DEVICE_CAP_FREQ_VALID) ? _("unknown") :
+                                                     ((wcaps & NM_WIFI_DEVICE_CAP_FREQ_2GHZ) ? _("yes") : _("no")));
+                               set_val_strc (arr, 9, !(wcaps & NM_WIFI_DEVICE_CAP_FREQ_VALID) ? _("unknown") :
+                                                     ((wcaps & NM_WIFI_DEVICE_CAP_FREQ_5GHZ) ? _("yes") : _("no")));
                                g_ptr_array_add (nmc->output_data, arr);
 
                                print_data (nmc);  /* Print all data */
index 7d4d73c..d1c5313 100644 (file)
       <tp:flag suffix="ADHOC" value="0x80">
         <tp:docstring>The device supports Ad-Hoc mode.</tp:docstring>
       </tp:flag>
+      <tp:flag suffix="FREQ_VALID" value="0x100">
+       <tp:docstring>
+         The device properly reports information about supported
+         frequencies and thus both NM_802_11_DEVICE_CAP_FREQ_2GHZ and
+         NM_802_11_DEVICE_CAP_FREQ_5GHZ are valid.
+       </tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="FREQ_2GHZ" value="0x200">
+        <tp:docstring>
+          The device supports 2.4GHz frequencies.
+        </tp:docstring>
+      </tp:flag>
+      <tp:flag suffix="FREQ_5GHZ" value="0x400">
+        <tp:docstring>
+          The device supports 5GHz frequencies.
+        </tp:docstring>
+      </tp:flag>
     </tp:flags>
   </interface>
 </node>
index 04a822c..9bab80f 100644 (file)
@@ -199,6 +199,9 @@ typedef enum { /*< flags >*/
  * @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication
  * @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode
  * @NM_WIFI_DEVICE_CAP_ADHOC: device supports Ad-Hoc mode
+ * @NM_WIFI_DEVICE_CAP_FREQ_VALID: device reports frequency capabilities
+ * @NM_WIFI_DEVICE_CAP_FREQ_2GHZ: device supports 2.4GHz frequencies
+ * @NM_WIFI_DEVICE_CAP_FREQ_5GHZ: device supports 5GHz frequencies
  *
  * 802.11 specific device encryption and authentication capabilities.
  *
@@ -213,7 +216,10 @@ typedef enum { /*< flags >*/
        NM_WIFI_DEVICE_CAP_WPA           = 0x00000010,
        NM_WIFI_DEVICE_CAP_RSN           = 0x00000020,
        NM_WIFI_DEVICE_CAP_AP            = 0x00000040,
-       NM_WIFI_DEVICE_CAP_ADHOC         = 0x00000080
+       NM_WIFI_DEVICE_CAP_ADHOC         = 0x00000080,
+       NM_WIFI_DEVICE_CAP_FREQ_VALID    = 0x00000100,
+       NM_WIFI_DEVICE_CAP_FREQ_2GHZ     = 0x00000200,
+       NM_WIFI_DEVICE_CAP_FREQ_5GHZ     = 0x00000400,
 } NMDeviceWifiCapabilities;
 
 
index 4557a87..5a98b8e 100644 (file)
@@ -204,6 +204,9 @@ typedef enum {
  * @NM_WIFI_DEVICE_CAP_RSN: device supports WPA2/RSN authentication
  * @NM_WIFI_DEVICE_CAP_AP: device supports Access Point mode
  * @NM_WIFI_DEVICE_CAP_ADHOC: device supports Ad-Hoc mode
+ * @NM_WIFI_DEVICE_CAP_FREQ_VALID: device reports frequency capabilities
+ * @NM_WIFI_DEVICE_CAP_FREQ_2GHZ: device supports 2.4GHz frequencies
+ * @NM_WIFI_DEVICE_CAP_FREQ_5GHZ: device supports 5GHz frequencies
  *
  * 802.11 specific device encryption and authentication capabilities.
  *
@@ -218,7 +221,10 @@ typedef enum {
        NM_WIFI_DEVICE_CAP_WPA           = 0x00000010,
        NM_WIFI_DEVICE_CAP_RSN           = 0x00000020,
        NM_WIFI_DEVICE_CAP_AP            = 0x00000040,
-       NM_WIFI_DEVICE_CAP_ADHOC         = 0x00000080
+       NM_WIFI_DEVICE_CAP_ADHOC         = 0x00000080,
+       NM_WIFI_DEVICE_CAP_FREQ_VALID    = 0x00000100,
+       NM_WIFI_DEVICE_CAP_FREQ_2GHZ     = 0x00000200,
+       NM_WIFI_DEVICE_CAP_FREQ_5GHZ     = 0x00000400,
 } NMDeviceWifiCapabilities;
 
 
index fd69d17..8ca5dd1 100644 (file)
@@ -756,6 +756,7 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
                }
        }
 
+       /* Find number of supported frequencies */
        info->num_freqs = 0;
 
        nla_for_each_nested (nl_band, tb[NL80211_ATTR_WIPHY_BANDS], rem_band) {
@@ -775,6 +776,7 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
                }
        }
 
+       /* Read supported frequencies */
        info->freqs = g_malloc0 (sizeof (guint32) * info->num_freqs);
 
        freq_idx = 0;
@@ -793,10 +795,19 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg)
 
                        info->freqs[freq_idx] =
                                nla_get_u32 (tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
+
+                       info->caps |= NM_WIFI_DEVICE_CAP_FREQ_VALID;
+
+                       if (info->freqs[freq_idx] > 2400 && info->freqs[freq_idx] < 2500)
+                               info->caps |= NM_WIFI_DEVICE_CAP_FREQ_2GHZ;
+                       if (info->freqs[freq_idx] > 4900 && info->freqs[freq_idx] < 6000)
+                               info->caps |= NM_WIFI_DEVICE_CAP_FREQ_5GHZ;
+
                        freq_idx++;
                }
        }
 
+       /* Read security/encryption support */
        if (tb[NL80211_ATTR_CIPHER_SUITES]) {
                int num;
                int i;
index 8be3677..f4301ef 100644 (file)
@@ -593,6 +593,7 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan)
        guint32 response_len = 0;
        struct iw_range_with_scan_capa *scan_capa_range;
        int i;
+       gboolean freq_valid = FALSE, has_5ghz = FALSE, has_2ghz = FALSE;
 
        wext = wifi_data_new (iface, ifindex, sizeof (*wext));
        wext->parent.get_mode = wifi_wext_get_mode;
@@ -634,8 +635,14 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan)
        wext->max_qual.updated = range.max_qual.updated;
 
        wext->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES);
-       for (i = 0; i < wext->num_freqs; i++)
+       for (i = 0; i < wext->num_freqs; i++) {
                wext->freqs[i] = iw_freq_to_uint32 (&range.freq[i]);
+               freq_valid = TRUE;
+               if (wext->freqs[i] > 2400 && wext->freqs[i] < 2500)
+                       has_2ghz = TRUE;
+               else if (wext->freqs[i] > 4900 && wext->freqs[i] < 6000)
+                       has_5ghz = TRUE;
+       }
 
        /* Check for scanning capability; cards that can't scan are not supported */
        if (check_scan && (wext_can_scan (wext) == FALSE)) {
@@ -663,6 +670,12 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan)
        }
 
        wext->parent.caps = wext_get_caps (wext, &range);
+       if (freq_valid)
+               wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_VALID;
+       if (has_2ghz)
+               wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_2GHZ;
+       if (has_5ghz)
+               wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_5GHZ;
 
        nm_log_info (LOGD_HW | LOGD_WIFI,
                     "(%s): using WEXT for WiFi device control",
index ea58f89..b25e708 100644 (file)
@@ -44,7 +44,8 @@ gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode);
 /* Returns frequency in MHz */
 guint32 wifi_utils_get_freq (WifiData *data);
 
-/* Return the first supported frequency in the zero-terminated list */
+/* Return the first supported frequency in the zero-terminated list.
+ * Frequencies are specified in MHz. */
 guint32 wifi_utils_find_freq (WifiData *data, const guint32 *freqs);
 
 /* Caller must free returned byte array */