1#!/usr/bin/env python 2# 3# rfkill control code 4# 5# Copyright (c) 2015 Intel Corporation 6# 7# Author: Johannes Berg <johannes.berg@intel.com> 8# 9# This software may be distributed under the terms of the BSD license. 10# See README for more details. 11 12import struct 13import fcntl 14import os 15 16(TYPE_ALL, 17 TYPE_WLAN, 18 TYPE_BLUETOOTH, 19 TYPE_UWB, 20 TYPE_WIMAX, 21 TYPE_WWAN, 22 TYPE_GPS, 23 TYPE_FM, 24 TYPE_NFC) = list(range(9)) 25 26(_OP_ADD, 27 _OP_DEL, 28 _OP_CHANGE, 29 _OP_CHANGE_ALL) = list(range(4)) 30 31_type_names = { 32 TYPE_ALL: "all", 33 TYPE_WLAN: "Wireless LAN", 34 TYPE_BLUETOOTH: "Bluetooth", 35 TYPE_UWB: "Ultra-Wideband", 36 TYPE_WIMAX: "WiMAX", 37 TYPE_WWAN: "Wireless WAN", 38 TYPE_GPS: "GPS", 39 TYPE_FM: "FM", 40 TYPE_NFC: "NFC", 41} 42 43# idx, type, op, soft, hard 44_event_struct = '@IBBBB' 45_event_sz = struct.calcsize(_event_struct) 46 47class RFKillException(Exception): 48 pass 49 50class RFKill(object): 51 def __init__(self, idx): 52 self._idx = idx 53 self._type = None 54 55 @property 56 def idx(self): 57 return self._idx 58 59 @property 60 def name(self): 61 return open('/sys/class/rfkill/rfkill%d/name' % self._idx, 'r').read().rstrip() 62 63 @property 64 def type(self): 65 if not self._type: 66 for r, s, h in RFKill.list(): 67 if r.idx == self.idx: 68 self._type = r._type 69 break 70 return self._type 71 72 @property 73 def type_name(self): 74 return _type_names.get(self._type, "unknown") 75 76 @property 77 def blocked(self): 78 l = RFKill.list() 79 for r, s, h in l: 80 if r.idx == self.idx: 81 return (s, h) 82 raise RFKillException("RFKill instance no longer exists") 83 84 @property 85 def soft_blocked(self): 86 return self.blocked[0] 87 88 @soft_blocked.setter 89 def soft_blocked(self, block): 90 if block: 91 self.block() 92 else: 93 self.unblock() 94 95 @property 96 def hard_blocked(self): 97 return self.blocked[1] 98 99 def block(self): 100 rfk = open('/dev/rfkill', 'wb') 101 s = struct.pack(_event_struct, self.idx, TYPE_ALL, _OP_CHANGE, 1, 0) 102 rfk.write(s) 103 rfk.close() 104 105 def unblock(self): 106 rfk = open('/dev/rfkill', 'wb') 107 s = struct.pack(_event_struct, self.idx, TYPE_ALL, _OP_CHANGE, 0, 0) 108 rfk.write(s) 109 rfk.close() 110 111 @classmethod 112 def block_all(cls, t=TYPE_ALL): 113 rfk = open('/dev/rfkill', 'wb') 114 print(rfk) 115 s = struct.pack(_event_struct, 0, t, _OP_CHANGE_ALL, 1, 0) 116 rfk.write(s) 117 rfk.close() 118 119 @classmethod 120 def unblock_all(cls, t=TYPE_ALL): 121 rfk = open('/dev/rfkill', 'wb') 122 s = struct.pack(_event_struct, 0, t, _OP_CHANGE_ALL, 0, 0) 123 rfk.write(s) 124 rfk.close() 125 126 @classmethod 127 def list(cls): 128 res = [] 129 rfk = open('/dev/rfkill', 'rb', buffering=0) 130 fd = rfk.fileno() 131 flgs = fcntl.fcntl(fd, fcntl.F_GETFL) 132 fcntl.fcntl(fd, fcntl.F_SETFL, flgs | os.O_NONBLOCK) 133 while True: 134 try: 135 d = rfk.read(_event_sz) 136 if d == None: 137 break 138 _idx, _t, _op, _s, _h = struct.unpack(_event_struct, d) 139 if _op != _OP_ADD: 140 continue 141 r = RFKill(_idx) 142 r._type = _t 143 res.append((r, _s, _h)) 144 except IOError: 145 break 146 return res 147 148if __name__ == "__main__": 149 for r, s, h in RFKill.list(): 150 print("%d: %s: %s" % (r.idx, r.name, r.type_name)) 151 print("\tSoft blocked: %s" % ("yes" if s else "no")) 152 print("\tHard blocked: %s" % ("yes" if h else "no")) 153