led-blinker.c 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <errno.h>
  5. #include <unistd.h>
  6. #define BUFFER_SIZE 64
  7. // use sysfs to control the LED on connected device
  8. int main(int argc, char *argv[]) {
  9. FILE *f;
  10. char buf[BUFFER_SIZE];
  11. char *sysfs_LEDS = "/sys/class/leds/";
  12. // go to sysfs node, this preempts the need to concatenate user data (argv)
  13. if(0 != chdir(sysfs_LEDS)) {
  14. fprintf(stderr, "failed to change directory to %s\n", sysfs_LEDS);
  15. return 1;
  16. }
  17. // [?] argc is one when no parameters supplied and argv[0] is program name
  18. if(/* less than two parameters, terminate with error */ 2 > argc) {
  19. fprintf(stderr, "must provide sysfs device name\n");
  20. // short when we cannot provide user with list of device names
  21. if(NULL == (f = popen("ls", "r"))) return 1;
  22. // provide user with list of possible device names
  23. fprintf(stderr, "you might want to try:\n");
  24. while(NULL != fgets(buf, BUFFER_SIZE, f)) fprintf(stderr, "%s", buf);
  25. pclose(f);
  26. return 1;
  27. }
  28. // make sure supplied device name is short and is mostly alpha-numeric
  29. for(uint8_t i = 0; i < BUFFER_SIZE; i++) {
  30. char comp = argv[1][i];
  31. uint8_t okay = 0;
  32. if('-' == comp || '_' == comp || '\0' == comp) okay |= 1;
  33. if('a' <= comp && 'z' >= comp) okay |= 1;
  34. if('A' <= comp && 'Z' >= comp) okay |= 1;
  35. if('0' <= comp && '9' >= comp) okay |= 1;
  36. // terminate if device name is not okay
  37. if(! okay) fprintf(stderr, "Can not deal with this device name.\n");
  38. // terminate if device name is really long
  39. if(BUFFER_SIZE - 1 == i && '\0' != comp) {
  40. fprintf(stderr, "Device name might be too long.\n");
  41. // clear okay flag so we can fail out
  42. okay = 0;
  43. }
  44. if(! okay) return 1;
  45. // short if we are done before BUFFER_SIZE characters
  46. if('\0' == comp) break;
  47. }
  48. // [!] argv contains at most 64 of: a..z A..Z 0..9 hyphen or underscore
  49. if(0 != chdir(argv[1])) {
  50. fprintf(stderr, "failed to change directory to %s\n", argv[1]);
  51. return 1;
  52. }
  53. // make sure we are in control of the led, not some other source
  54. { if(NULL == (f = fopen("trigger", "r+"))) {
  55. fprintf(stderr, "error when opening the trigger: %s\n", strerror(errno));
  56. return 1;
  57. }
  58. if(-1 == fwrite("none\n", 1, 5, f)) {
  59. fprintf(stderr, "couldn't write \"none\" to trigger: %s\n", strerror(errno));
  60. return 1;
  61. }
  62. fclose(f);
  63. }
  64. // blink the leds, on for a second, off for a second
  65. uint8_t state = 0;
  66. while(1) {
  67. // on every loop, reopen the file to make sure it is still there
  68. { if(NULL == (f = fopen("brightness", "r+"))) {
  69. fprintf(stderr, "oh no: %s\n", strerror(errno));
  70. return 1;
  71. }
  72. if(-1 == fwrite(state ?"1\n" :"0\n", 1, 2, f)) {
  73. fprintf(stderr, "uh oh setting \"%d\" led: %s\n", state, strerror(errno));
  74. return 1;
  75. }
  76. fclose(f);
  77. }
  78. // one second on, one second off
  79. sleep(1);
  80. // toggle state on ... off ... on ... off ...
  81. state = !state;
  82. }
  83. }