rfkill.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* rfkill.c - Enable/disable wireless devices.
  2. *
  3. * Copyright 2014 Ranjan Kumar <ranjankumar.bth@gmail.com>
  4. * Copyright 2014 Kyungwan Han <asura321@gmail.com>
  5. *
  6. * No Standard
  7. USE_RFKILL(NEWTOY(rfkill, "<1>2", TOYFLAG_USR|TOYFLAG_SBIN))
  8. config RFKILL
  9. bool "rfkill"
  10. default y
  11. help
  12. usage: rfkill COMMAND [DEVICE]
  13. Enable/disable wireless devices.
  14. Commands:
  15. list [DEVICE] List current state
  16. block DEVICE Disable device
  17. unblock DEVICE Enable device
  18. DEVICE is an index number, or one of:
  19. all, wlan(wifi), bluetooth, uwb(ultrawideband), wimax, wwan, gps, fm.
  20. */
  21. #define FOR_rfkill
  22. #include "toys.h"
  23. #include <linux/rfkill.h>
  24. void rfkill_main(void)
  25. {
  26. struct rfkill_event rfevent;
  27. int fd, tvar, idx = -1, tid = RFKILL_TYPE_ALL;
  28. char **optargs = toys.optargs;
  29. // Parse command line options
  30. for (tvar = 0; tvar < 3; tvar++)
  31. if (!strcmp((char *[]){"list", "block", "unblock"}[tvar], *optargs)) break;
  32. if (tvar == 3) error_exit("unknown cmd '%s'", *optargs);
  33. if (tvar) {
  34. int i;
  35. struct arglist {
  36. char *name;
  37. int idx;
  38. } rftypes[] = {{"all", RFKILL_TYPE_ALL}, {"wifi", RFKILL_TYPE_WLAN},
  39. {"wlan", RFKILL_TYPE_WLAN}, {"bluetooth", RFKILL_TYPE_BLUETOOTH},
  40. {"uwb", RFKILL_TYPE_UWB}, {"ultrawideband", RFKILL_TYPE_UWB},
  41. {"wimax", RFKILL_TYPE_WIMAX}, {"wwan", RFKILL_TYPE_WWAN},
  42. {"gps", RFKILL_TYPE_GPS}, {"fm", 7}}; // RFKILL_TYPE_FM = 7
  43. if (!*++optargs) error_exit("'%s' needs IDENTIFIER", optargs[-1]);
  44. for (i = 0; i < ARRAY_LEN(rftypes); i++)
  45. if (!strcmp(rftypes[i].name, *optargs)) break;
  46. if (i == ARRAY_LEN(rftypes)) idx = atolx_range(*optargs, 0, INT_MAX);
  47. else tid = rftypes[i].idx;
  48. }
  49. // Perform requested action
  50. fd = xopen("/dev/rfkill", (tvar ? O_RDWR : O_RDONLY)|O_NONBLOCK);
  51. if (tvar) {
  52. // block/unblock
  53. memset(&rfevent, 0, sizeof(rfevent));
  54. rfevent.soft = tvar == 1;
  55. if (idx >= 0) {
  56. rfevent.idx = idx;
  57. rfevent.op = RFKILL_OP_CHANGE;
  58. } else {
  59. rfevent.type = tid;
  60. rfevent.op = RFKILL_OP_CHANGE_ALL;
  61. }
  62. xwrite(fd, &rfevent, sizeof(rfevent));
  63. } else {
  64. // show list.
  65. while (sizeof(rfevent) == readall(fd, &rfevent, sizeof(rfevent))) {
  66. char *line = 0, *name = 0, *type = 0;
  67. FILE *fp;
  68. size_t l = 0;
  69. ssize_t len;
  70. // filter list items
  71. if ((tid > 0 && tid != rfevent.type) || (idx != -1 && idx != rfevent.idx))
  72. continue;
  73. sprintf(toybuf, "/sys/class/rfkill/rfkill%u/uevent", rfevent.idx);
  74. fp = xfopen(toybuf, "r");
  75. while ((len = getline(&line, &l, fp)) > 0) {
  76. char *s = line;
  77. line[len-1] = 0;
  78. if (strstart(&s, "RFKILL_NAME=")) name = xstrdup(s);
  79. else if (strstart(&s, "RFKILL_TYPE=")) type = xstrdup(s);
  80. }
  81. free(line);
  82. fclose(fp);
  83. xprintf("%u: %s: %s\n", rfevent.idx, name, type);
  84. xprintf("\tSoft blocked: %s\n", rfevent.soft ? "yes" : "no");
  85. xprintf("\tHard blocked: %s\n", rfevent.hard ? "yes" : "no");
  86. free(name);
  87. free(type);
  88. }
  89. }
  90. xclose(fd);
  91. }