-
Notifications
You must be signed in to change notification settings - Fork 70
/
rfkill.c
58 lines (48 loc) · 1.9 KB
/
rfkill.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
* Routines to check and describe the rfkill state of a wireless interface.
*
* Based on https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-rfkill
*/
#include "iw_if.h"
#include <string.h>
/** Return human-friendly description of @state. */
const char *rfkill_state_name(const rfkill_state_t state) {
static const char *states[] = {
[RFKILL_STATE_UNDEFINED] = "unknown",
[RFKILL_STATE_UNBLOCKED] = "unblocked",
[RFKILL_STATE_SOFT_BLOCKED] = "software RF-kill",
[RFKILL_STATE_HARD_BLOCKED] = "hardware RF-kill",
[RFKILL_STATE_FULL_BLOCKED] = "hardware/software RF-kill",
};
return states[state];
}
/** Return true if @state indicates that RF-kill is active. */
bool is_rfkill_blocked_state(const rfkill_state_t state) {
return state != RFKILL_STATE_UNBLOCKED && state != RFKILL_STATE_UNDEFINED;
}
/** Determine the rfkill state of wireless interface identified by @wdev_index. */
rfkill_state_t get_rfkill_state(const uint32_t wdev_index) {
rfkill_state_t state = RFKILL_STATE_UNDEFINED;
char wdev_state_path[256];
uint32_t val;
snprintf(wdev_state_path, sizeof(wdev_state_path) - 1,
"/sys/class/rfkill/rfkill%u/hard", wdev_index);
if (read_number_file(wdev_state_path, &val) != 1)
return RFKILL_STATE_UNDEFINED;
state = val ? RFKILL_STATE_HARD_BLOCKED : RFKILL_STATE_UNBLOCKED;
snprintf(wdev_state_path, sizeof(wdev_state_path) - 1,
"/sys/class/rfkill/rfkill%u/soft", wdev_index);
if (read_number_file(wdev_state_path, &val) != 1)
return RFKILL_STATE_UNDEFINED;
if (!val)
return state;
if (state == RFKILL_STATE_HARD_BLOCKED)
return RFKILL_STATE_FULL_BLOCKED;
return RFKILL_STATE_SOFT_BLOCKED;
}
/** Return true if the configured wireless interface is be blocked by rfkill. */
bool default_interface_is_rfkill_blocked(void) {
struct interface_info *data = NULL;
iw_nl80211_get_interface_data(&data);
return data && is_rfkill_blocked_state(get_rfkill_state(data->wdev));
}