diff options
-rw-r--r-- | rfkill/.gitignore | 5 | ||||
-rw-r--r-- | rfkill/COPYING | 15 | ||||
-rw-r--r-- | rfkill/Makefile | 62 | ||||
-rw-r--r-- | rfkill/README | 12 | ||||
-rw-r--r-- | rfkill/core.h | 8 | ||||
-rw-r--r-- | rfkill/rfkill.8 | 38 | ||||
-rw-r--r-- | rfkill/rfkill.c | 357 | ||||
-rw-r--r-- | rfkill/rfkill.h | 109 | ||||
-rwxr-xr-x | rfkill/rfkill.py | 150 | ||||
-rwxr-xr-x | rfkill/version.sh | 32 |
10 files changed, 788 insertions, 0 deletions
diff --git a/rfkill/.gitignore b/rfkill/.gitignore new file mode 100644 index 000000000..528816db0 --- /dev/null +++ b/rfkill/.gitignore @@ -0,0 +1,5 @@ +version.c +*.o +rfkill +*~ +*.gz diff --git a/rfkill/COPYING b/rfkill/COPYING new file mode 100644 index 000000000..58265cdc9 --- /dev/null +++ b/rfkill/COPYING @@ -0,0 +1,15 @@ +Copyright 2009 Johannes Berg <johannes@sipsolutions.net> +Copyright 2009 Marcel Holtmann <marcel@holtmann.org> +Copyright 2009 Tim Gardner <tim.gardner@canonical.com> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/rfkill/Makefile b/rfkill/Makefile new file mode 100644 index 000000000..8d6c700be --- /dev/null +++ b/rfkill/Makefile @@ -0,0 +1,62 @@ +MAKEFLAGS += --no-print-directory + +PREFIX ?= /usr +SBINDIR ?= $(PREFIX)/sbin +MANDIR ?= $(PREFIX)/share/man + +MKDIR ?= mkdir -p +INSTALL ?= install +CC ?= "gcc" + +CFLAGS ?= -O2 -g +CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration + +OBJS = rfkill.o version.o +ALL = rfkill + +ifeq ($(V),1) +Q= +NQ=true +else +Q=@ +NQ=echo +endif + +all: $(ALL) + +VERSION_OBJS := $(filter-out version.o, $(OBJS)) + +version.c: version.sh $(patsubst %.o,%.c,$(VERSION_OBJS)) rfkill.h Makefile \ + $(wildcard .git/index .git/refs/tags) + @$(NQ) ' GEN ' $@ +ifeq (,$(VERSION_SUFFIX)) + $(Q)./version.sh $@ +else + $(Q)./version.sh --suffix "$(VERSION_SUFFIX)" $@ +endif + +%.o: %.c rfkill.h + @$(NQ) ' CC ' $@ + $(Q)$(CC) $(CFLAGS) -c -o $@ $< + +rfkill: $(OBJS) + @$(NQ) ' CC ' rfkill + $(Q)$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o rfkill + +check: + $(Q)$(MAKE) all CC="REAL_CC=$(CC) CHECK=\"sparse -Wall\" cgcc" + +%.gz: % + @$(NQ) ' GZIP' $< + $(Q)gzip < $< > $@ + +install: rfkill rfkill.8.gz + @$(NQ) ' INST rfkill' + $(Q)$(MKDIR) $(DESTDIR)$(SBINDIR) + $(Q)$(INSTALL) -m 755 -t $(DESTDIR)$(SBINDIR) rfkill + @$(NQ) ' INST rfkill.8' + $(Q)$(MKDIR) $(DESTDIR)$(MANDIR)/man8/ + $(Q)$(INSTALL) -m 644 -t $(DESTDIR)$(MANDIR)/man8/ rfkill.8.gz + +clean: + $(Q)rm -f rfkill *.o *~ *.gz version.c *-stamp diff --git a/rfkill/README b/rfkill/README new file mode 100644 index 000000000..0f5dafe33 --- /dev/null +++ b/rfkill/README @@ -0,0 +1,12 @@ + +This is 'rfkill', a tool to use /dev/rfkill. + + +To build rfkill, just enter 'make'. + +'rfkill' is currently maintained at http://git.sipsolutions.net/rfkill.git/, +some more documentation is available at +http://wireless.kernel.org/en/users/Documentation/rfkill. + +Please send all patches to Johannes Berg <johannes@sipsolutions.net> +and CC linux-wireless@vger.kernel.org for community review. diff --git a/rfkill/core.h b/rfkill/core.h new file mode 100644 index 000000000..56cde4044 --- /dev/null +++ b/rfkill/core.h @@ -0,0 +1,8 @@ +#ifndef __CORE +#define __CORE + +#include "rfkill.h" + +extern const char rfkill_version[]; + +#endif diff --git a/rfkill/rfkill.8 b/rfkill/rfkill.8 new file mode 100644 index 000000000..24baccc67 --- /dev/null +++ b/rfkill/rfkill.8 @@ -0,0 +1,38 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH RFKILL 8 "July 10, 2009" +.SH NAME +rfkill \- tool for enabling and disabling wireless devices +.SH SYNOPSIS +.B rfkill +.RI [ options ] " command" +.SH OPTIONS +.TP +.B \-\-version +Show the version of rfkill. +.SH COMMANDS +.TP +.B help +Show rfkill's built-in help text. +.TP +.B event +Listen for rfkill events and display them on stdout. +.TP +.B list [type] +List the current state of all available rfkill-using devices, +or just all of the given type. +.TP +.BI block " index|type" +Disable the device corresponding to the given index. +\fItype\fR is one of "all", "wifi", "wlan", "bluetooth", "uwb", +"ultrawideband", "wimax", "wwan", "gps", "fm" or "nfc". +.TP +.BI unblock " index|type" +Enable the device corresponding to the given index. If the device is +hard-blocked, e.g. via a hardware switch, it will remain unavailable though +it is now soft-unblocked. +.SH AUTHORS +rfkill was originally written by Johannes Berg <johannes@sipsolutions.net> +and Marcel Holtmann <marcel@holtmann.org>. +.PP +This manual page was written by Darren Salt <linux@youmustbejoking.demon.co.uk>, +for the Debian project (and may be used by others). diff --git a/rfkill/rfkill.c b/rfkill/rfkill.c new file mode 100644 index 000000000..8cd81fed9 --- /dev/null +++ b/rfkill/rfkill.c @@ -0,0 +1,357 @@ +/* + * rfkill userspace tool + */ + +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> +#include <sys/types.h> +#include <sys/poll.h> +#include <sys/time.h> + +#include "rfkill.h" +#include "core.h" + +static void rfkill_event(void) +{ + struct rfkill_event event; + struct timeval tv; + struct pollfd p; + ssize_t len; + int fd, n; + + fd = open("/dev/rfkill", O_RDONLY); + if (fd < 0) { + perror("Can't open RFKILL control device"); + return; + } + + memset(&p, 0, sizeof(p)); + p.fd = fd; + p.events = POLLIN | POLLHUP; + + while (1) { + n = poll(&p, 1, -1); + if (n < 0) { + perror("Failed to poll RFKILL control device"); + break; + } + + if (n == 0) + continue; + + len = read(fd, &event, sizeof(event)); + if (len < 0) { + perror("Reading of RFKILL events failed"); + break; + } + + if (len != RFKILL_EVENT_SIZE_V1) { + fprintf(stderr, "Wrong size of RFKILL event\n"); + continue; + } + + gettimeofday(&tv, NULL); + printf("%ld.%06u: idx %u type %u op %u soft %u hard %u\n", + (long) tv.tv_sec, (unsigned int) tv.tv_usec, + event.idx, event.type, event.op, event.soft, event.hard); + fflush(stdout); + } + + close(fd); +} + +static const char *get_name(__u32 idx) +{ + static char name[128] = {}; + char *pos, filename[64]; + int fd; + + snprintf(filename, sizeof(filename) - 1, + "/sys/class/rfkill/rfkill%u/name", idx); + + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + + memset(name, 0, sizeof(name)); + read(fd, name, sizeof(name) - 1); + + pos = strchr(name, '\n'); + if (pos) + *pos = '\0'; + + close(fd); + + return name; +} + +static const char *type2string(enum rfkill_type type) +{ + switch (type) { + case RFKILL_TYPE_ALL: + return "All"; + case RFKILL_TYPE_WLAN: + return "Wireless LAN"; + case RFKILL_TYPE_BLUETOOTH: + return "Bluetooth"; + case RFKILL_TYPE_UWB: + return "Ultra-Wideband"; + case RFKILL_TYPE_WIMAX: + return "WiMAX"; + case RFKILL_TYPE_WWAN: + return "Wireless WAN"; + case RFKILL_TYPE_GPS: + return "GPS"; + case RFKILL_TYPE_FM: + return "FM"; + case RFKILL_TYPE_NFC: + return "NFC"; + case NUM_RFKILL_TYPES: + return NULL; + } + + return NULL; +} + +struct rfkill_type_str { + enum rfkill_type type; + const char *name; +}; +static const struct rfkill_type_str rfkill_type_strings[] = { + { .type = RFKILL_TYPE_ALL, .name = "all" }, + { .type = RFKILL_TYPE_WLAN, .name = "wifi" }, + { .type = RFKILL_TYPE_WLAN, .name = "wlan" }, /* alias */ + { .type = RFKILL_TYPE_BLUETOOTH, .name = "bluetooth" }, + { .type = RFKILL_TYPE_UWB, .name = "uwb" }, + { .type = RFKILL_TYPE_UWB, .name = "ultrawideband" }, /* alias */ + { .type = RFKILL_TYPE_WIMAX, .name = "wimax" }, + { .type = RFKILL_TYPE_WWAN, .name = "wwan" }, + { .type = RFKILL_TYPE_GPS, .name = "gps" }, + { .type = RFKILL_TYPE_FM, .name = "fm" }, + { .type = RFKILL_TYPE_NFC, .name = "nfc" }, + { .name = NULL } +}; + +struct rfkill_id { + union { + enum rfkill_type type; + __u32 index; + }; + enum { + RFKILL_IS_INVALID, + RFKILL_IS_TYPE, + RFKILL_IS_INDEX, + } result; +}; + +static struct rfkill_id rfkill_id_to_type(const char *s) +{ + const struct rfkill_type_str *p; + struct rfkill_id ret; + + if (islower(*s)) { + for (p = rfkill_type_strings; p->name != NULL; p++) { + if ((strlen(s) == strlen(p->name)) && (!strcmp(s,p->name))) { + ret.type = p->type; + ret.result = RFKILL_IS_TYPE; + return ret; + } + } + } else if (isdigit(*s)) { + /* assume a numeric character implies an index. */ + ret.index = atoi(s); + ret.result = RFKILL_IS_INDEX; + return ret; + } + + ret.result = RFKILL_IS_INVALID; + return ret; +} + +static int rfkill_list(const char *param) +{ + struct rfkill_id id = { .result = RFKILL_IS_INVALID }; + struct rfkill_event event; + const char *name; + ssize_t len; + int fd; + + if (param) { + id = rfkill_id_to_type(param); + if (id.result == RFKILL_IS_INVALID) { + fprintf(stderr, "Bogus %s argument '%s'.\n", "list", param); + return 2; + } + /* don't filter "all" */ + if (id.result == RFKILL_IS_TYPE && id.type == RFKILL_TYPE_ALL) + id.result = RFKILL_IS_INVALID; + } + + fd = open("/dev/rfkill", O_RDONLY); + if (fd < 0) { + perror("Can't open RFKILL control device"); + return 1; + } + + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { + perror("Can't set RFKILL control device to non-blocking"); + close(fd); + return 1; + } + + while (1) { + len = read(fd, &event, sizeof(event)); + if (len < 0) { + if (errno == EAGAIN) + break; + perror("Reading of RFKILL events failed"); + break; + } + + if (len != RFKILL_EVENT_SIZE_V1) { + fprintf(stderr, "Wrong size of RFKILL event\n"); + continue; + } + + if (event.op != RFKILL_OP_ADD) + continue; + + /* filter out unwanted results */ + switch (id.result) + { + case RFKILL_IS_TYPE: + if (event.type != id.type) + continue; + break; + case RFKILL_IS_INDEX: + if (event.idx != id.index) + continue; + break; + case RFKILL_IS_INVALID:; /* must be last */ + } + + name = get_name(event.idx); + + printf("%u: %s: %s\n", event.idx, name, + type2string(event.type)); + printf("\tSoft blocked: %s\n", event.soft ? "yes" : "no"); + printf("\tHard blocked: %s\n", event.hard ? "yes" : "no"); + } + + close(fd); + return 0; +} + +static int rfkill_block(__u8 block, const char *param) +{ + struct rfkill_id id; + struct rfkill_event event; + ssize_t len; + int fd; + + id = rfkill_id_to_type(param); + if (id.result == RFKILL_IS_INVALID) { + fprintf(stderr, "Bogus %s argument '%s'.\n", block ? "block" : "unblock", param); + return 2; + } + + fd = open("/dev/rfkill", O_RDWR); + if (fd < 0) { + perror("Can't open RFKILL control device"); + return 1; + } + + memset(&event, 0, sizeof(event)); + switch (id.result) { + case RFKILL_IS_TYPE: + event.op = RFKILL_OP_CHANGE_ALL; + event.type = id.type; + break; + case RFKILL_IS_INDEX: + event.op = RFKILL_OP_CHANGE; + event.idx = id.index; + break; + case RFKILL_IS_INVALID:; /* must be last */ + } + event.soft = block; + + len = write(fd, &event, sizeof(event)); + if (len < 0) + perror("Failed to change RFKILL state"); + + close(fd); + return 0; +} + +static const char *argv0; + +static void usage(void) +{ + const struct rfkill_type_str *p; + + fprintf(stderr, "Usage:\t%s [options] command\n", argv0); + fprintf(stderr, "Options:\n"); + fprintf(stderr, "\t--version\tshow version (%s)\n", rfkill_version); + fprintf(stderr, "Commands:\n"); + fprintf(stderr, "\thelp\n"); + fprintf(stderr, "\tevent\n"); + fprintf(stderr, "\tlist [IDENTIFIER]\n"); + fprintf(stderr, "\tblock IDENTIFIER\n"); + fprintf(stderr, "\tunblock IDENTIFIER\n"); + fprintf(stderr, "where IDENTIFIER is the index no. of an rfkill switch or one of:\n"); + fprintf(stderr, "\t<idx>"); + for (p = rfkill_type_strings; p->name != NULL; p++) + fprintf(stderr, " %s", p->name); + fprintf(stderr, "\n"); +} + +static void version(void) +{ + printf("rfkill %s\n", rfkill_version); +} + +int main(int argc, char **argv) +{ + int ret = 0; + + /* strip off self */ + argc--; + argv0 = *argv++; + + if (argc > 0 && strcmp(*argv, "--version") == 0) { + version(); + return 0; + } + + if (argc == 0 || strcmp(*argv, "help") == 0) { + usage(); + return 0; + } + + if (strcmp(*argv, "event") == 0) { + rfkill_event(); + } else if (strcmp(*argv, "list") == 0) { + argc--; + argv++; + rfkill_list(*argv); /* NULL is acceptable */ + } else if (strcmp(*argv, "block") == 0 && argc > 1) { + argc--; + argv++; + ret = rfkill_block(1,*argv); + } else if (strcmp(*argv, "unblock") == 0 && argc > 1) { + argc--; + argv++; + ret = rfkill_block(0,*argv); + } else { + usage(); + return 1; + } + + return ret; +} diff --git a/rfkill/rfkill.h b/rfkill/rfkill.h new file mode 100644 index 000000000..058757f7a --- /dev/null +++ b/rfkill/rfkill.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2006 - 2007 Ivo van Doorn + * Copyright (C) 2007 Dmitry Torokhov + * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef _UAPI__RFKILL_H +#define _UAPI__RFKILL_H + + +#include <linux/types.h> + +/* define userspace visible states */ +#define RFKILL_STATE_SOFT_BLOCKED 0 +#define RFKILL_STATE_UNBLOCKED 1 +#define RFKILL_STATE_HARD_BLOCKED 2 + +/** + * enum rfkill_type - type of rfkill switch. + * + * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type) + * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device. + * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device. + * @RFKILL_TYPE_UWB: switch is on a ultra wideband device. + * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device. + * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device. + * @RFKILL_TYPE_GPS: switch is on a GPS device. + * @RFKILL_TYPE_FM: switch is on a FM radio device. + * @RFKILL_TYPE_NFC: switch is on an NFC device. + * @NUM_RFKILL_TYPES: number of defined rfkill types + */ +enum rfkill_type { + RFKILL_TYPE_ALL = 0, + RFKILL_TYPE_WLAN, + RFKILL_TYPE_BLUETOOTH, + RFKILL_TYPE_UWB, + RFKILL_TYPE_WIMAX, + RFKILL_TYPE_WWAN, + RFKILL_TYPE_GPS, + RFKILL_TYPE_FM, + RFKILL_TYPE_NFC, + NUM_RFKILL_TYPES, +}; + +/** + * enum rfkill_operation - operation types + * @RFKILL_OP_ADD: a device was added + * @RFKILL_OP_DEL: a device was removed + * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device + * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all) + */ +enum rfkill_operation { + RFKILL_OP_ADD = 0, + RFKILL_OP_DEL, + RFKILL_OP_CHANGE, + RFKILL_OP_CHANGE_ALL, +}; + +/** + * struct rfkill_event - events for userspace on /dev/rfkill + * @idx: index of dev rfkill + * @type: type of the rfkill struct + * @op: operation code + * @hard: hard state (0/1) + * @soft: soft state (0/1) + * + * Structure used for userspace communication on /dev/rfkill, + * used for events from the kernel and control to the kernel. + */ +struct rfkill_event { + __u32 idx; + __u8 type; + __u8 op; + __u8 soft, hard; +} __attribute__((packed)); + +/* + * We are planning to be backward and forward compatible with changes + * to the event struct, by adding new, optional, members at the end. + * When reading an event (whether the kernel from userspace or vice + * versa) we need to accept anything that's at least as large as the + * version 1 event size, but might be able to accept other sizes in + * the future. + * + * One exception is the kernel -- we already have two event sizes in + * that we've made the 'hard' member optional since our only option + * is to ignore it anyway. + */ +#define RFKILL_EVENT_SIZE_V1 8 + +/* ioctl for turning off rfkill-input (if present) */ +#define RFKILL_IOC_MAGIC 'R' +#define RFKILL_IOC_NOINPUT 1 +#define RFKILL_IOCTL_NOINPUT _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT) + +/* and that's all userspace gets */ + +#endif /* _UAPI__RFKILL_H */ diff --git a/rfkill/rfkill.py b/rfkill/rfkill.py new file mode 100755 index 000000000..57dcddc06 --- /dev/null +++ b/rfkill/rfkill.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python +# +# rfkill control code +# +# Copyright (c) 2015 Intel Corporation +# +# Author: Johannes Berg <johannes.berg@intel.com> +# +# This software may be distributed under the terms of the MIT license. +# See COPYING for more details. + +import struct +import fcntl +import os + +(TYPE_ALL, + TYPE_WLAN, + TYPE_BLUETOOTH, + TYPE_UWB, + TYPE_WIMAX, + TYPE_WWAN, + TYPE_GPS, + TYPE_FM, + TYPE_NFC) = range(9) + +(_OP_ADD, + _OP_DEL, + _OP_CHANGE, + _OP_CHANGE_ALL) = range(4) + +_type_names = { + TYPE_ALL: "all", + TYPE_WLAN: "Wireless LAN", + TYPE_BLUETOOTH: "Bluetooth", + TYPE_UWB: "Ultra-Wideband", + TYPE_WIMAX: "WiMAX", + TYPE_WWAN: "Wireless WAN", + TYPE_GPS: "GPS", + TYPE_FM: "FM", + TYPE_NFC: "NFC", +} + +# idx, type, op, soft, hard +_event_struct = '@IBBBB' +_event_sz = struct.calcsize(_event_struct) + +class RFKillException(Exception): + pass + +class RFKill(object): + def __init__(self, idx): + self._idx = idx + self._type = None + + @property + def idx(self): + return self._idx + + @property + def name(self): + return open('/sys/class/rfkill/rfkill%d/name' % self._idx, 'r').read().rstrip() + + @property + def type(self): + if not self._type: + for r, s, h in RFKill.list(): + if r.idx == self.idx: + self._type = r._type + break + return self._type + + @property + def type_name(self): + return _type_names.get(self._type, "unknown") + + @property + def blocked(self): + l = RFKill.list() + for r, s, h in l: + if r.idx == self.idx: + return (s, h) + raise RFKillException("RFKill instance no longer exists") + + @property + def soft_blocked(self): + return self.blocked[0] + + @soft_blocked.setter + def soft_blocked(self, block): + if block: + self.block() + else: + self.unblock() + + @property + def hard_blocked(self): + return self.blocked[1] + + def block(self): + rfk = open('/dev/rfkill', 'w') + s = struct.pack(_event_struct, self.idx, TYPE_ALL, _OP_CHANGE, 1, 0) + rfk.write(s) + rfk.close() + + def unblock(self): + rfk = open('/dev/rfkill', 'w') + s = struct.pack(_event_struct, self.idx, TYPE_ALL, _OP_CHANGE, 0, 0) + rfk.write(s) + rfk.close() + + @classmethod + def block_all(cls, t=TYPE_ALL): + rfk = open('/dev/rfkill', 'w') + print rfk + s = struct.pack(_event_struct, 0, t, _OP_CHANGE_ALL, 1, 0) + rfk.write(s) + rfk.close() + + @classmethod + def unblock_all(cls, t=TYPE_ALL): + rfk = open('/dev/rfkill', 'w') + s = struct.pack(_event_struct, 0, t, _OP_CHANGE_ALL, 0, 0) + rfk.write(s) + rfk.close() + + @classmethod + def list(cls): + res = [] + rfk = open('/dev/rfkill', 'r') + fd = rfk.fileno() + flgs = fcntl.fcntl(fd, fcntl.F_GETFL) + fcntl.fcntl(fd, fcntl.F_SETFL, flgs | os.O_NONBLOCK) + while True: + try: + d = rfk.read(_event_sz) + _idx, _t, _op, _s, _h = struct.unpack(_event_struct, d) + if _op != _OP_ADD: + continue + r = RFKill(_idx) + r._type = _t + res.append((r, _s, _h)) + except IOError: + break + return res + +if __name__ == "__main__": + for r, s, h in RFKill.list(): + print "%d: %s: %s" % (r.idx, r.name, r.type_name) + print "\tSoft blocked: %s" % ("yes" if s else "no") + print "\tHard blocked: %s" % ("yes" if h else "no") diff --git a/rfkill/version.sh b/rfkill/version.sh new file mode 100755 index 000000000..f2bcaace8 --- /dev/null +++ b/rfkill/version.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +VERSION="0.5" + +SUFFIX= +if test "x$1" = x--suffix; then + shift + SUFFIX="-$1" + shift +fi +OUT="$1" + +if test "x$SUFFIX" != 'x'; then + v="$VERSION$SUFFIX" +elif head=`git rev-parse --verify HEAD 2>/dev/null`; then + git update-index --refresh --unmerged > /dev/null + descr=$(git describe 2>/dev/null || echo "v$VERSION") + + # on git builds check that the version number above + # is correct... + [ "${descr%%-*}" = "v$VERSION" ] || exit 2 + + echo -n 'const char rfkill_version[] = "' > "$OUT" + v="${descr#v}" + if git diff-index --name-only HEAD | read dummy ; then + v="$v"-dirty + fi +else + v="$VERSION" +fi + +echo "const char rfkill_version[] = \"$v\";" > "$OUT" |