| /* rfkill.c - Enable/disable wireless devices. |
| * |
| * Copyright 2014 Ranjan Kumar <ranjankumar.bth@gmail.com> |
| * Copyright 2014 Kyungwan Han <asura321@gmail.com> |
| * |
| * No Standard |
| |
| USE_RFKILL(NEWTOY(rfkill, "<1>2", TOYFLAG_USR|TOYFLAG_SBIN)) |
| |
| config RFKILL |
| bool "rfkill" |
| default y |
| help |
| Usage: rfkill COMMAND [DEVICE] |
| |
| Enable/disable wireless devices. |
| |
| Commands: |
| list [DEVICE] List current state |
| block DEVICE Disable device |
| unblock DEVICE Enable device |
| |
| DEVICE is an index number, or one of: |
| all, wlan(wifi), bluetooth, uwb(ultrawideband), wimax, wwan, gps, fm. |
| */ |
| |
| #define FOR_rfkill |
| #include "toys.h" |
| #include <linux/rfkill.h> |
| |
| void rfkill_main(void) |
| { |
| struct rfkill_event rfevent; |
| int fd, tvar, idx = -1, tid = RFKILL_TYPE_ALL; |
| char **optargs = toys.optargs; |
| |
| // Parse command line options |
| for (tvar = 0; tvar < 3; tvar++) |
| if (!strcmp((char *[]){"list", "block", "unblock"}[tvar], *optargs)) break; |
| if (tvar == 3) error_exit("unknown cmd '%s'", *optargs); |
| if (tvar) { |
| int i; |
| struct arglist { |
| char *name; |
| int idx; |
| } rftypes[] = {{"all", RFKILL_TYPE_ALL}, {"wifi", RFKILL_TYPE_WLAN}, |
| {"wlan", RFKILL_TYPE_WLAN}, {"bluetooth", RFKILL_TYPE_BLUETOOTH}, |
| {"uwb", RFKILL_TYPE_UWB}, {"ultrawideband", RFKILL_TYPE_UWB}, |
| {"wimax", RFKILL_TYPE_WIMAX}, {"wwan", RFKILL_TYPE_WWAN}, |
| {"gps", RFKILL_TYPE_GPS}, {"fm", 7}}; // RFKILL_TYPE_FM = 7 |
| |
| if (!*++optargs) error_exit("'%s' needs IDENTIFIER", optargs[-1]); |
| for (i = 0; i < ARRAY_LEN(rftypes); i++) |
| if (!strcmp(rftypes[i].name, *optargs)) break; |
| if (i == ARRAY_LEN(rftypes)) idx = atolx_range(*optargs, 0, INT_MAX); |
| else tid = rftypes[i].idx; |
| } |
| |
| // Perform requested action |
| fd = xopen("/dev/rfkill", (tvar ? O_RDWR : O_RDONLY)|O_NONBLOCK); |
| if (tvar) { |
| // block/unblock |
| memset(&rfevent, 0, sizeof(rfevent)); |
| rfevent.soft = tvar == 1; |
| if (idx >= 0) { |
| rfevent.idx = idx; |
| rfevent.op = RFKILL_OP_CHANGE; |
| } else { |
| rfevent.type = tid; |
| rfevent.op = RFKILL_OP_CHANGE_ALL; |
| } |
| xwrite(fd, &rfevent, sizeof(rfevent)); |
| } else { |
| // show list. |
| while (sizeof(rfevent) == readall(fd, &rfevent, sizeof(rfevent))) { |
| char *line, *name = 0, *type = 0; |
| |
| // filter list items |
| if ((tid > 0 && tid != rfevent.type) || (idx != -1 && idx != rfevent.idx)) |
| continue; |
| |
| sprintf(toybuf, "/sys/class/rfkill/rfkill%u/uevent", rfevent.idx); |
| tvar = xopenro(toybuf); |
| while ((line = get_line(tvar))) { |
| char *s = line; |
| |
| if (strstart(&s, "RFKILL_NAME=")) name = xstrdup(s); |
| else if (strstart(&s, "RFKILL_TYPE=")) type = xstrdup(s); |
| |
| free(line); |
| } |
| xclose(tvar); |
| |
| xprintf("%u: %s: %s\n", rfevent.idx, name, type); |
| xprintf("\tSoft blocked: %s\n", rfevent.soft ? "yes" : "no"); |
| xprintf("\tHard blocked: %s\n", rfevent.hard ? "yes" : "no"); |
| free(name); |
| free(type); |
| } |
| } |
| xclose(fd); |
| } |