summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2018-02-26 22:19:09 +0000
committerRoy Marples <roy@marples.name>2018-02-26 22:19:09 +0000
commit826be7a3c19a54ca671f8501f15ab048f335aa9a (patch)
treec8eaf3dd05b91e9b2de0372e2fbfdf91d928428a
parenta9d3ad5fac70218f83fea01e735a8b6d6c034a2c (diff)
wpa: add better frequency support.
Add flags indicate if a given AP is 2G, 5G or both. When a wpa_supplicant connection is made, set the frequency for the connected interface.
-rw-r--r--src/dhcpcd-gtk/menu.c15
-rw-r--r--src/libdhcpcd/dhcpcd.c2
-rw-r--r--src/libdhcpcd/dhcpcd.h22
-rw-r--r--src/libdhcpcd/wpa.c105
4 files changed, 128 insertions, 16 deletions
diff --git a/src/dhcpcd-gtk/menu.c b/src/dhcpcd-gtk/menu.c
index 1c554ba..96d0893 100644
--- a/src/dhcpcd-gtk/menu.c
+++ b/src/dhcpcd-gtk/menu.c
@@ -101,7 +101,7 @@ is_associated(WI_SCAN *wi, DHCPCD_WI_SCAN *scan)
}
static bool
-get_security_icon(int flags, const char **icon)
+get_security_icon(unsigned int flags, const char **icon)
{
bool active;
@@ -124,6 +124,9 @@ update_item(WI_SCAN *wi, WI_MENU *m, DHCPCD_WI_SCAN *scan)
const char *icon;
GtkWidget *sel;
bool active;
+#if 0
+ char tip[256];
+#endif
m->scan = scan;
@@ -159,14 +162,8 @@ update_item(WI_SCAN *wi, WI_MENU *m, DHCPCD_WI_SCAN *scan)
GTK_ICON_SIZE_MENU);
#if 0
- if (scan->wpa_flags[0] == '\0')
- gtk_widget_set_tooltip_text(m->menu, scan->bssid);
- else {
- char *tip = g_strconcat(scan->bssid, " ", scan->wpa_flags,
- NULL);
- gtk_widget_set_tooltip_text(m->menu, tip);
- g_free(tip);
- }
+ dhcpcd_wi_print_tooltip(tip, sizeof(tip), scan, 0);
+ gtk_widget_set_tooltip_text(m->menu, tip);
#endif
g_object_set_data(G_OBJECT(m->menu), "dhcpcd_wi_scan", scan);
diff --git a/src/libdhcpcd/dhcpcd.c b/src/libdhcpcd/dhcpcd.c
index 64dfb23..62b21ea 100644
--- a/src/libdhcpcd/dhcpcd.c
+++ b/src/libdhcpcd/dhcpcd.c
@@ -401,6 +401,7 @@ dhcpcd_decode_string_escape(char *dst, size_t dlen, const char *src)
}
if (dst)
*dst++ = (char)oct;
+ break;
default:
errno = EINVAL;
return -1;
@@ -831,6 +832,7 @@ dhcpcd_new_if(DHCPCD_CONNECTION *con, char *data, size_t len)
i->up = strtobool(dhcpcd_get_value(i, "if_up"));
i->wireless = strtobool(dhcpcd_get_value(i, "ifwireless"));
i->ssid = dhcpcd_get_value(i, "ifssid");
+ i->freq = 0; /* wpa_supplicant will set this when opened */
if (i->ssid == NULL && i->wireless)
i->ssid = dhcpcd_get_value(i, i->up ? "new_ssid" : "old_ssid");
diff --git a/src/libdhcpcd/dhcpcd.h b/src/libdhcpcd/dhcpcd.h
index cc7e989..ed9eb54 100644
--- a/src/libdhcpcd/dhcpcd.h
+++ b/src/libdhcpcd/dhcpcd.h
@@ -67,6 +67,9 @@ extern "C" {
#define TYPESIZE 8
#define REASONSIZE 16
+#define WPA_FREQ_IS_2G(f) ((f) >= 2402 && (f) <= 2472)
+#define WPA_FREQ_IS_5G(f) ((f) >= 5170 && (f) <= 5835)
+
#define DHC_UNKNOWN 0
#define DHC_DOWN 1
#define DHC_OPENED 2
@@ -121,11 +124,13 @@ typedef struct dhcpcd_wi_avs {
typedef struct dhcpcd_wi_scan {
struct dhcpcd_wi_scan *next;
char bssid[IF_BSSIDSIZE];
- int flags;
-#define WSF_SECURE 0x01
-#define WSF_PSK 0x02
-#define WSF_WEP 0x10
-#define WSF_WPA 0x20
+ unsigned int flags;
+#define WSF_SECURE 0x001
+#define WSF_PSK 0x002
+#define WSF_WEP 0x010
+#define WSF_WPA 0x020
+#define WSF_2G 0x100
+#define WSF_5G 0x200
int frequency;
DHCPCD_WI_AV quality;
DHCPCD_WI_AV noise;
@@ -147,6 +152,7 @@ typedef struct dhcpcd_if {
bool up;
bool wireless;
const char *ssid;
+ int freq;
char *data;
size_t data_len;
@@ -167,6 +173,7 @@ typedef struct dhcpcd_if {
bool up;
bool wireless;
const char *ssid;
+ int freq;
} DHCPCD_IF;
#endif
@@ -304,6 +311,11 @@ int dhcpcd_wpa_find_network_new(DHCPCD_WPA *, const char *);
bool dhcpcd_wpa_command(DHCPCD_WPA *, const char *);
bool dhcpcd_wpa_command_arg(DHCPCD_WPA *, const char *, const char *);
unsigned int dhcpcd_wpa_status(DHCPCD_WPA *, const char **);
+int dhcpcd_wpa_freq(DHCPCD_WPA *);
+#define WST_BSSID 0x01
+#define WST_FLAGS 0x02
+#define WST_FREQ 0x03
+int dhcpcd_wi_print_tooltip(char *, size_t, DHCPCD_WI_SCAN *, unsigned int);
bool dhcpcd_wpa_ping(DHCPCD_WPA *);
bool dhcpcd_wpa_can_background_scan(DHCPCD_WPA *);
diff --git a/src/libdhcpcd/wpa.c b/src/libdhcpcd/wpa.c
index baf674b..f872ea5 100644
--- a/src/libdhcpcd/wpa.c
+++ b/src/libdhcpcd/wpa.c
@@ -69,7 +69,7 @@ wpa_open(const char *ifname, char **path)
fd = r = -1;
*path = NULL;
- pwdbufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ pwdbufsize = (size_t)sysconf(_SC_GETPW_R_SIZE_MAX);
pwdbuf = malloc(pwdbufsize);
if (pwdbuf == NULL)
goto out;
@@ -570,6 +570,18 @@ dhcpcd_wi_scans_sort(DHCPCD_WI_SCAN *list)
}
}
+static unsigned int
+dhcpcd_wi_freqflags(DHCPCD_WI_SCAN *w)
+{
+
+ if (WPA_FREQ_IS_2G(w->frequency))
+ return WSF_2G;
+ if (WPA_FREQ_IS_5G(w->frequency))
+ return WSF_5G;
+ /* Unknown frequency */
+ return 0;
+}
+
DHCPCD_WI_SCAN *
dhcpcd_wi_scans(DHCPCD_IF *i)
{
@@ -599,13 +611,18 @@ dhcpcd_wi_scans(DHCPCD_IF *i)
}
/* Strip duplicated SSIDs, only show the strongest */
if (p && strcmp(p->ssid, w->ssid) == 0) {
+ /* Set frequency flag from the duplicate */
+ p->flags |= dhcpcd_wi_freqflags(w);
p->next = n;
free(w);
continue;
}
- /* Remember this as the previos next time */
+ /* Remember this as the previous next time */
p = w;
+ /* Set frequency flags */
+ p->flags |= dhcpcd_wi_freqflags(w);
+
nh = 1;
hl = NULL;
w->quality.average = w->quality.value;
@@ -959,6 +976,26 @@ dhcpcd_wpa_if(DHCPCD_WPA *wpa)
return dhcpcd_get_if(wpa->con, wpa->ifname, DHT_LINK);
}
+static void
+dhcpcd_wpa_if_freq(DHCPCD_WPA *wpa)
+{
+ DHCPCD_IF *i;
+
+ i = dhcpcd_wpa_if(wpa);
+ if (i != NULL)
+ i->freq = dhcpcd_wpa_freq(wpa);
+}
+
+static void
+dhcpcd_wpa_if_freq_zero(DHCPCD_WPA *wpa)
+{
+ DHCPCD_IF *i;
+
+ i = dhcpcd_wpa_if(wpa);
+ if (i != NULL)
+ i->freq = 0;
+}
+
int
dhcpcd_wpa_open(DHCPCD_WPA *wpa)
{
@@ -991,6 +1028,8 @@ dhcpcd_wpa_open(DHCPCD_WPA *wpa)
return -1;
}
+ dhcpcd_wpa_if_freq(wpa);
+
dhcpcd_wpa_update_status(wpa, DHC_CONNECTED);
if (wpa->con->wi_scanresults_cb)
wpa->con->wi_scanresults_cb(wpa,
@@ -1078,6 +1117,10 @@ dhcpcd_wpa_dispatch(DHCPCD_WPA *wpa)
wpa->con->wi_scanresults_cb)
wpa->con->wi_scanresults_cb(wpa,
wpa->con->wi_scanresults_context);
+ else if (strcmp(p, "CTRL-EVENT-CONNECTED") == 0)
+ dhcpcd_wpa_if_freq(wpa);
+ else if (strcmp(p, "CTRL-EVENT-DISCONNECTED") == 0)
+ dhcpcd_wpa_if_freq_zero(wpa);
else if (strcmp(p, "CTRL-EVENT-TERMINATING") == 0)
dhcpcd_wpa_close(wpa);
}
@@ -1234,3 +1277,61 @@ dhcpcd_wpa_select(DHCPCD_WPA *wpa, DHCPCD_WI_SCAN *s)
}
return retval;
}
+
+int
+dhcpcd_wpa_freq(DHCPCD_WPA *wpa)
+{
+ char buf[256], *p, *s;
+ ssize_t bytes;
+ int freq;
+
+ bytes = wpa_cmd(wpa->command_fd, "STATUS", buf, sizeof(buf));
+ if (bytes == 0 || bytes == -1)
+ return false;
+
+ p = buf;
+ while ((s = strsep(&p, "\n"))) {
+ if (*s == '\0')
+ continue;
+ if (strncmp(s, "freq=", 5) == 0) {
+ dhcpcd_strtoi(&freq, s + 5);
+ return freq;
+ }
+ }
+
+ errno = ENOENT;
+ return 0;
+}
+
+int
+dhcpcd_wi_print_tooltip(char *buf, size_t buflen, DHCPCD_WI_SCAN *s,
+ unsigned int options)
+{
+ int r, printed = 0;
+
+ /* Provide a default */
+ if (options == 0)
+ options = WST_BSSID | WST_FREQ;
+
+#define TOOLTIP(fmt, ...) do { \
+ r = snprintf(buf, buflen, fmt, __VA_ARGS__); \
+ if (r == -1 || (size_t)r > buflen) \
+ return printed + r; \
+ buf += r; \
+ buflen -= (size_t)r; \
+ printed += r; \
+ } while (0 /* CONSTCOND */)
+
+ if (options & WST_BSSID)
+ TOOLTIP("%s", s->bssid);
+ if (options & WST_FLAGS && s->wpa_flags[0] != '\0')
+ TOOLTIP(" %s", s->wpa_flags);
+ if (options & WST_FREQ) {
+ if (s->flags & WSF_2G)
+ TOOLTIP(" %s", "2G");
+ if (s->flags & WSF_5G)
+ TOOLTIP(" %s", "5G");
+ }
+
+ return printed;
+}