1/* vi: set sw=4 ts=4: */ 2/* 3* rfkill implementation for busybox 4* 5* Copyright (C) 2010 Malek Degachi <malek-degachi@laposte.net> 6* 7* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 8*/ 9#include "libbb.h" 10#include <linux/rfkill.h> 11 12enum { 13 OPT_b = (1 << 0), /* must be = 1 */ 14 OPT_u = (1 << 1), 15 OPT_l = (1 << 2), 16}; 17 18int rfkill_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 19int rfkill_main(int argc UNUSED_PARAM, char **argv) 20{ 21 struct rfkill_event event; 22 const char *rf_name; 23 int rf_fd; 24 int mode; 25 int rf_type; 26 int rf_idx; 27 unsigned rf_opt = 0; 28 29 argv++; 30 /* Must have one or two params */ 31 if (!argv[0] || (argv[1] && argv[2])) 32 bb_show_usage(); 33 34 mode = O_RDWR | O_NONBLOCK; 35 rf_name = argv[1]; 36 if (strcmp(argv[0], "list") == 0) { 37 rf_opt |= OPT_l; 38 mode = O_RDONLY | O_NONBLOCK; 39 } else if (strcmp(argv[0], "block") == 0 && rf_name) { 40 rf_opt |= OPT_b; 41 } else if (strcmp(argv[0], "unblock") == 0 && rf_name) { 42 rf_opt |= OPT_u; 43 } else 44 bb_show_usage(); 45 46 rf_type = RFKILL_TYPE_ALL; 47 rf_idx = -1; 48 if (rf_name) { 49 static const char rfkill_types[] ALIGN1 = "all\0wlan\0bluetooth\0uwb\0wimax\0wwan\0gps\0fm\0"; 50 if (strcmp(rf_name, "wifi") == 0) 51 rf_name = "wlan"; 52 if (strcmp(rf_name, "ultrawideband") == 0) 53 rf_name = "uwb"; 54 rf_type = index_in_strings(rfkill_types, rf_name); 55 if (rf_type < 0) { 56 rf_idx = xatoi_u(rf_name); 57 } 58 } 59 60 rf_fd = device_open("/dev/rfkill", mode); 61 if (rf_fd < 0) 62 bb_perror_msg_and_die("/dev/rfkill"); 63 64 if (rf_opt & OPT_l) { 65 while (full_read(rf_fd, &event, sizeof(event)) == RFKILL_EVENT_SIZE_V1) { 66 parser_t *parser; 67 char *tokens[2]; 68 char rf_sysfs[sizeof("/sys/class/rfkill/rfkill%u/uevent") + sizeof(int)*3]; 69 char *name, *type; 70 71 if (rf_type && rf_type != event.type && rf_idx < 0) { 72 continue; 73 } 74 75 if (rf_idx >= 0 && event.idx != rf_idx) { 76 continue; 77 } 78 79 name = NULL; 80 type = NULL; 81 sprintf(rf_sysfs, "/sys/class/rfkill/rfkill%u/uevent", event.idx); 82 parser = config_open2(rf_sysfs, fopen_for_read); 83 while (config_read(parser, tokens, 2, 2, "\n=", PARSE_NORMAL)) { 84 if (strcmp(tokens[0], "RFKILL_NAME") == 0) { 85 name = xstrdup(tokens[1]); 86 continue; 87 } 88 if (strcmp(tokens[0], "RFKILL_TYPE") == 0) { 89 type = xstrdup(tokens[1]); 90 continue; 91 } 92 } 93 config_close(parser); 94 95 printf("%u: %s: %s\n", event.idx, name, type); 96 printf("\tSoft blocked: %s\n", event.soft ? "yes" : "no"); 97 printf("\tHard blocked: %s\n", event.hard ? "yes" : "no"); 98 free(name); 99 free(type); 100 } 101 } else { 102 memset(&event, 0, sizeof(event)); 103 if (rf_type >= 0) { 104 event.type = rf_type; 105 event.op = RFKILL_OP_CHANGE_ALL; 106 } 107 108 if (rf_idx >= 0) { 109 event.idx = rf_idx; 110 event.op = RFKILL_OP_CHANGE; 111 } 112 113 /* Note: OPT_b == 1 */ 114 event.soft = (rf_opt & OPT_b); 115 116 xwrite(rf_fd, &event, sizeof(event)); 117 } 118 119 return EXIT_SUCCESS; 120} 121