rfkill.c 2.8 KB

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