Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (C) 2006 - 2007 Ivo van Doorn
0003  * Copyright (C) 2007 Dmitry Torokhov
0004  * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
0005  *
0006  * Permission to use, copy, modify, and/or distribute this software for any
0007  * purpose with or without fee is hereby granted, provided that the above
0008  * copyright notice and this permission notice appear in all copies.
0009  *
0010  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0011  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0012  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0013  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0014  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0015  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0016  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0017  */
0018 #ifndef _UAPI__RFKILL_H
0019 #define _UAPI__RFKILL_H
0020 
0021 
0022 #include <linux/types.h>
0023 
0024 /* define userspace visible states */
0025 #define RFKILL_STATE_SOFT_BLOCKED   0
0026 #define RFKILL_STATE_UNBLOCKED      1
0027 #define RFKILL_STATE_HARD_BLOCKED   2
0028 
0029 /**
0030  * enum rfkill_type - type of rfkill switch.
0031  *
0032  * @RFKILL_TYPE_ALL: toggles all switches (requests only - not a switch type)
0033  * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
0034  * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
0035  * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
0036  * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
0037  * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device.
0038  * @RFKILL_TYPE_GPS: switch is on a GPS device.
0039  * @RFKILL_TYPE_FM: switch is on a FM radio device.
0040  * @RFKILL_TYPE_NFC: switch is on an NFC device.
0041  * @NUM_RFKILL_TYPES: number of defined rfkill types
0042  */
0043 enum rfkill_type {
0044     RFKILL_TYPE_ALL = 0,
0045     RFKILL_TYPE_WLAN,
0046     RFKILL_TYPE_BLUETOOTH,
0047     RFKILL_TYPE_UWB,
0048     RFKILL_TYPE_WIMAX,
0049     RFKILL_TYPE_WWAN,
0050     RFKILL_TYPE_GPS,
0051     RFKILL_TYPE_FM,
0052     RFKILL_TYPE_NFC,
0053     NUM_RFKILL_TYPES,
0054 };
0055 
0056 /**
0057  * enum rfkill_operation - operation types
0058  * @RFKILL_OP_ADD: a device was added
0059  * @RFKILL_OP_DEL: a device was removed
0060  * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device
0061  * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all)
0062  *  into a state, also updating the default state used for devices that
0063  *  are hot-plugged later.
0064  */
0065 enum rfkill_operation {
0066     RFKILL_OP_ADD = 0,
0067     RFKILL_OP_DEL,
0068     RFKILL_OP_CHANGE,
0069     RFKILL_OP_CHANGE_ALL,
0070 };
0071 
0072 /**
0073  * enum rfkill_hard_block_reasons - hard block reasons
0074  * @RFKILL_HARD_BLOCK_SIGNAL: the hardware rfkill signal is active
0075  * @RFKILL_HARD_BLOCK_NOT_OWNER: the NIC is not owned by the host
0076  */
0077 enum rfkill_hard_block_reasons {
0078     RFKILL_HARD_BLOCK_SIGNAL    = 1 << 0,
0079     RFKILL_HARD_BLOCK_NOT_OWNER = 1 << 1,
0080 };
0081 
0082 /**
0083  * struct rfkill_event - events for userspace on /dev/rfkill
0084  * @idx: index of dev rfkill
0085  * @type: type of the rfkill struct
0086  * @op: operation code
0087  * @hard: hard state (0/1)
0088  * @soft: soft state (0/1)
0089  *
0090  * Structure used for userspace communication on /dev/rfkill,
0091  * used for events from the kernel and control to the kernel.
0092  */
0093 struct rfkill_event {
0094     __u32 idx;
0095     __u8  type;
0096     __u8  op;
0097     __u8  soft;
0098     __u8  hard;
0099 } __attribute__((packed));
0100 
0101 /**
0102  * struct rfkill_event_ext - events for userspace on /dev/rfkill
0103  * @idx: index of dev rfkill
0104  * @type: type of the rfkill struct
0105  * @op: operation code
0106  * @hard: hard state (0/1)
0107  * @soft: soft state (0/1)
0108  * @hard_block_reasons: valid if hard is set. One or several reasons from
0109  *  &enum rfkill_hard_block_reasons.
0110  *
0111  * Structure used for userspace communication on /dev/rfkill,
0112  * used for events from the kernel and control to the kernel.
0113  *
0114  * See the extensibility docs below.
0115  */
0116 struct rfkill_event_ext {
0117     __u32 idx;
0118     __u8  type;
0119     __u8  op;
0120     __u8  soft;
0121     __u8  hard;
0122 
0123     /*
0124      * older kernels will accept/send only up to this point,
0125      * and if extended further up to any chunk marked below
0126      */
0127 
0128     __u8  hard_block_reasons;
0129 } __attribute__((packed));
0130 
0131 /**
0132  * DOC: Extensibility
0133  *
0134  * Originally, we had planned to allow backward and forward compatible
0135  * changes by just adding fields at the end of the structure that are
0136  * then not reported on older kernels on read(), and not written to by
0137  * older kernels on write(), with the kernel reporting the size it did
0138  * accept as the result.
0139  *
0140  * This would have allowed userspace to detect on read() and write()
0141  * which kernel structure version it was dealing with, and if was just
0142  * recompiled it would have gotten the new fields, but obviously not
0143  * accessed them, but things should've continued to work.
0144  *
0145  * Unfortunately, while actually exercising this mechanism to add the
0146  * hard block reasons field, we found that userspace (notably systemd)
0147  * did all kinds of fun things not in line with this scheme:
0148  *
0149  * 1. treat the (expected) short writes as an error;
0150  * 2. ask to read sizeof(struct rfkill_event) but then compare the
0151  *    actual return value to RFKILL_EVENT_SIZE_V1 and treat any
0152  *    mismatch as an error.
0153  *
0154  * As a consequence, just recompiling with a new struct version caused
0155  * things to no longer work correctly on old and new kernels.
0156  *
0157  * Hence, we've rolled back &struct rfkill_event to the original version
0158  * and added &struct rfkill_event_ext. This effectively reverts to the
0159  * old behaviour for all userspace, unless it explicitly opts in to the
0160  * rules outlined here by using the new &struct rfkill_event_ext.
0161  *
0162  * Additionally, some other userspace (bluez, g-s-d) was reading with a
0163  * large size but as streaming reads rather than message-based, or with
0164  * too strict checks for the returned size. So eventually, we completely
0165  * reverted this, and extended messages need to be opted in to by using
0166  * an ioctl:
0167  *
0168  *  ioctl(fd, RFKILL_IOCTL_MAX_SIZE, sizeof(struct rfkill_event_ext));
0169  *
0170  * Userspace using &struct rfkill_event_ext and the ioctl must adhere to
0171  * the following rules:
0172  *
0173  * 1. accept short writes, optionally using them to detect that it's
0174  *    running on an older kernel;
0175  * 2. accept short reads, knowing that this means it's running on an
0176  *    older kernel;
0177  * 3. treat reads that are as long as requested as acceptable, not
0178  *    checking against RFKILL_EVENT_SIZE_V1 or such.
0179  */
0180 #define RFKILL_EVENT_SIZE_V1    sizeof(struct rfkill_event)
0181 
0182 /* ioctl for turning off rfkill-input (if present) */
0183 #define RFKILL_IOC_MAGIC    'R'
0184 #define RFKILL_IOC_NOINPUT  1
0185 #define RFKILL_IOCTL_NOINPUT    _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT)
0186 #define RFKILL_IOC_MAX_SIZE 2
0187 #define RFKILL_IOCTL_MAX_SIZE   _IOW(RFKILL_IOC_MAGIC, RFKILL_IOC_MAX_SIZE, __u32)
0188 
0189 /* and that's all userspace gets */
0190 
0191 #endif /* _UAPI__RFKILL_H */