18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Linux rfkill helper functions for driver wrappers
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <fcntl.h>
117d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt#include <limits.h>
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rfkill.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define RFKILL_EVENT_SIZE_V1 8
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct rfkill_event {
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 idx;
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 type;
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 op;
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 soft;
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 hard;
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} STRUCT_PACKED;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum rfkill_operation {
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_OP_ADD = 0,
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_OP_DEL,
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_OP_CHANGE,
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_OP_CHANGE_ALL,
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum rfkill_type {
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_ALL = 0,
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_WLAN,
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_BLUETOOTH,
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_UWB,
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_WIMAX,
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_WWAN,
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_GPS,
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	RFKILL_TYPE_FM,
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	NUM_RFKILL_TYPES,
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct rfkill_data {
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct rfkill_config *cfg;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int fd;
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int blocked;
517d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	uint32_t idx;
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt};
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void rfkill_receive(int sock, void *eloop_ctx, void *sock_ctx)
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct rfkill_data *rfkill = eloop_ctx;
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct rfkill_event event;
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssize_t len;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int new_blocked;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = read(rfkill->fd, &event, sizeof(event));
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len < 0) {
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "rfkill: Event read failed: %s",
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   strerror(errno));
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len != RFKILL_EVENT_SIZE_V1) {
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "rfkill: Unexpected event size "
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%d (expected %d)",
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   (int) len, RFKILL_EVENT_SIZE_V1);
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
747d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	if (event.op != RFKILL_OP_CHANGE || event.idx != rfkill->idx)
757d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		return;
767d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "rfkill: event: idx=%u type=%d "
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "op=%u soft=%u hard=%u",
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   event.idx, event.type, event.op, event.soft,
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   event.hard);
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (event.hard) {
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "rfkill: WLAN hard blocked");
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		new_blocked = 1;
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (event.soft) {
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "rfkill: WLAN soft blocked");
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		new_blocked = 1;
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "rfkill: WLAN unblocked");
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		new_blocked = 0;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (new_blocked != rfkill->blocked) {
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		rfkill->blocked = new_blocked;
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (new_blocked)
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rfkill->cfg->blocked_cb(rfkill->cfg->ctx);
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rfkill->cfg->unblocked_cb(rfkill->cfg->ctx);
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct rfkill_data * rfkill_init(struct rfkill_config *cfg)
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct rfkill_data *rfkill;
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct rfkill_event event;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssize_t len;
1087d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	char *phy = NULL, *rfk_phy;
1097d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	char buf[24 + IFNAMSIZ + 1];
1107d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	char buf2[31 + 11 + 1];
1117d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	int found = 0;
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rfkill = os_zalloc(sizeof(*rfkill));
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rfkill == NULL)
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1177d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	os_snprintf(buf, sizeof(buf), "/sys/class/net/%s/phy80211",
1187d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		    cfg->ifname);
1197d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	phy = realpath(buf, NULL);
1207d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	if (!phy) {
1217d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		wpa_printf(MSG_INFO, "rfkill: Cannot get wiphy information");
1227d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		goto fail;
1237d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	}
1247d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rfkill->cfg = cfg;
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rfkill->fd = open("/dev/rfkill", O_RDONLY);
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rfkill->fd < 0) {
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "rfkill: Cannot open RFKILL control "
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "device");
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (fcntl(rfkill->fd, F_SETFL, O_NONBLOCK) < 0) {
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "rfkill: Cannot set non-blocking mode: "
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%s", strerror(errno));
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto fail2;
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (;;) {
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = read(rfkill->fd, &event, sizeof(event));
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len < 0) {
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (errno == EAGAIN)
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break; /* No more entries */
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "rfkill: Event read failed: %s",
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   strerror(errno));
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (len != RFKILL_EVENT_SIZE_V1) {
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "rfkill: Unexpected event size "
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "%d (expected %d)",
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   (int) len, RFKILL_EVENT_SIZE_V1);
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1547d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		if (event.op != RFKILL_OP_ADD ||
1557d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		    event.type != RFKILL_TYPE_WLAN)
1567d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt			continue;
1577d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt
1587d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		os_snprintf(buf2, sizeof(buf2),
1597d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt			    "/sys/class/rfkill/rfkill%d/device", event.idx);
1607d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		rfk_phy = realpath(buf2, NULL);
1617d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		if (!rfk_phy)
1627d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt			goto fail2;
1637d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		found = os_strcmp(phy, rfk_phy) == 0;
1647d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		free(rfk_phy);
1657d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt
1667d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		if (!found)
1677d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt			continue;
1687d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "rfkill: initial event: idx=%u type=%d "
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "op=%u soft=%u hard=%u",
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   event.idx, event.type, event.op, event.soft,
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   event.hard);
1737d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt
1747d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		rfkill->idx = event.idx;
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (event.hard) {
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "rfkill: WLAN hard blocked");
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rfkill->blocked = 1;
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (event.soft) {
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "rfkill: WLAN soft blocked");
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rfkill->blocked = 1;
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1827d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		break;
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1857d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	if (!found)
1867d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt		goto fail2;
1877d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt
18857c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt	free(phy);
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_read_sock(rfkill->fd, rfkill_receive, rfkill, NULL);
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return rfkill;
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail2:
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	close(rfkill->fd);
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail:
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(rfkill);
1977d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	/* use standard free function to match realpath() */
1987d56b75791f317618c9c3ff08a4cfc36c91c9611Dmitry Shmidt	free(phy);
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid rfkill_deinit(struct rfkill_data *rfkill)
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rfkill == NULL)
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rfkill->fd >= 0) {
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_unregister_read_sock(rfkill->fd);
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		close(rfkill->fd);
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(rfkill->cfg);
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(rfkill);
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint rfkill_is_blocked(struct rfkill_data *rfkill)
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rfkill == NULL)
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return rfkill->blocked;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
225