diff options
| author | Cy Schubert <cy@FreeBSD.org> | 2017-10-18 03:44:27 +0000 |
|---|---|---|
| committer | Cy Schubert <cy@FreeBSD.org> | 2017-10-18 03:44:27 +0000 |
| commit | 256810032c472505440606bd9c1c4f7dbf06b0a2 (patch) | |
| tree | d019f4f1ae29b86cbd3e9e74f832689976a267cf /src/drivers/rfkill.c | |
| parent | b834757ea3bcd1bba3381ff7cab216458d8f7efb (diff) | |
Diffstat (limited to 'src/drivers/rfkill.c')
| -rw-r--r-- | src/drivers/rfkill.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/src/drivers/rfkill.c b/src/drivers/rfkill.c index 45b26c46b69c7..4d4d1b4489fd4 100644 --- a/src/drivers/rfkill.c +++ b/src/drivers/rfkill.c @@ -8,6 +8,7 @@ #include "includes.h" #include <fcntl.h> +#include <limits.h> #include "utils/common.h" #include "utils/eloop.h" @@ -47,6 +48,7 @@ struct rfkill_data { struct rfkill_config *cfg; int fd; int blocked; + uint32_t idx; }; @@ -69,12 +71,13 @@ static void rfkill_receive(int sock, void *eloop_ctx, void *sock_ctx) (int) len, RFKILL_EVENT_SIZE_V1); return; } + if (event.op != RFKILL_OP_CHANGE || event.idx != rfkill->idx) + return; + wpa_printf(MSG_DEBUG, "rfkill: event: idx=%u type=%d " "op=%u soft=%u hard=%u", event.idx, event.type, event.op, event.soft, event.hard); - if (event.op != RFKILL_OP_CHANGE || event.type != RFKILL_TYPE_WLAN) - return; if (event.hard) { wpa_printf(MSG_INFO, "rfkill: WLAN hard blocked"); @@ -102,11 +105,23 @@ struct rfkill_data * rfkill_init(struct rfkill_config *cfg) struct rfkill_data *rfkill; struct rfkill_event event; ssize_t len; + char *phy = NULL, *rfk_phy; + char buf[24 + IFNAMSIZ + 1]; + char buf2[31 + 11 + 1]; + int found = 0; rfkill = os_zalloc(sizeof(*rfkill)); if (rfkill == NULL) return NULL; + os_snprintf(buf, sizeof(buf), "/sys/class/net/%s/phy80211", + cfg->ifname); + phy = realpath(buf, NULL); + if (!phy) { + wpa_printf(MSG_INFO, "rfkill: Cannot get wiphy information"); + goto fail; + } + rfkill->cfg = cfg; rfkill->fd = open("/dev/rfkill", O_RDONLY); if (rfkill->fd < 0) { @@ -136,13 +151,27 @@ struct rfkill_data * rfkill_init(struct rfkill_config *cfg) (int) len, RFKILL_EVENT_SIZE_V1); continue; } + if (event.op != RFKILL_OP_ADD || + event.type != RFKILL_TYPE_WLAN) + continue; + + os_snprintf(buf2, sizeof(buf2), + "/sys/class/rfkill/rfkill%d/device", event.idx); + rfk_phy = realpath(buf2, NULL); + if (!rfk_phy) + goto fail2; + found = os_strcmp(phy, rfk_phy) == 0; + free(rfk_phy); + + if (!found) + continue; + wpa_printf(MSG_DEBUG, "rfkill: initial event: idx=%u type=%d " "op=%u soft=%u hard=%u", event.idx, event.type, event.op, event.soft, event.hard); - if (event.op != RFKILL_OP_ADD || - event.type != RFKILL_TYPE_WLAN) - continue; + + rfkill->idx = event.idx; if (event.hard) { wpa_printf(MSG_INFO, "rfkill: WLAN hard blocked"); rfkill->blocked = 1; @@ -150,8 +179,13 @@ struct rfkill_data * rfkill_init(struct rfkill_config *cfg) wpa_printf(MSG_INFO, "rfkill: WLAN soft blocked"); rfkill->blocked = 1; } + break; } + if (!found) + goto fail2; + + free(phy); eloop_register_read_sock(rfkill->fd, rfkill_receive, rfkill, NULL); return rfkill; @@ -160,6 +194,8 @@ fail2: close(rfkill->fd); fail: os_free(rfkill); + /* use standard free function to match realpath() */ + free(phy); return NULL; } |
