diff --git a/README.md b/README.md index 6e1100d..9b8cec9 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A collection of tools and utility apps for the PINE64 PinePhone. ## Components ### backlight -Get / Set backlight brightness. +Get / Set display backlight brightness. ``` $ pptk-backlight get @@ -11,6 +11,19 @@ $ pptk-backlight get $ pptk-backlight set 6 ``` +### led +Get / Set LED light level for the RGB indicator and the white flash light. + +``` +# Get red RGB indicator brightness +$ pptk-led get red +255 +# Turn RED indicator OFF +$ pptk-led set red 0 +# Turn FLASH light ON +$ pptk-led set flash 255 +``` + ## Build & Install ``` $ meson build diff --git a/meson.build b/meson.build index 99590e2..80cb42c 100644 --- a/meson.build +++ b/meson.build @@ -1,3 +1,5 @@ project('PinePhone Toolkit', 'c') executable('pptk-backlight', ['src/backlight.c'], install: true, install_mode: ['rwsr-xr-x', 0, 0]) +executable('pptk-led', ['src/led.c'], + install: true, install_mode: ['rwsr-xr-x', 0, 0]) \ No newline at end of file diff --git a/src/led.c b/src/led.c new file mode 100644 index 0000000..77b0d6c --- /dev/null +++ b/src/led.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +static char *argv0 = "./led"; +static char *led_file_template = "/sys/class/leds/%s:%s/brightness"; + +void print_usage() +{ + printf("usage: %s COMMAND COLOR [VALUE]\n", argv0); + printf(" COMMAND = {get, set}\n"); + printf(" get ... prints LED level\n"); + printf(" set ... sets LED level to VALUE\n"); + printf(" COLOR = {red, green, blue, flash}\n"); + printf(" red ... red:indicator LED\n"); + printf(" green ... green:indicator LED\n"); + printf(" blue ... blue:indicator LED\n"); + printf(" flash ... white:flash LED\n"); + printf(" VALUE = [0..255] ... light level\n"); +} + +void print_usage_and_fail() +{ + print_usage(); + exit(EXIT_FAILURE); +} + +void command_get(char *filepath) +{ + FILE *fp = fopen(filepath, "r"); + if (fp == NULL) { + fprintf(stderr, "Cannot open file '%s' for reading.\n", filepath); + exit(EXIT_FAILURE); + } + int buffer_length = 255; + char buffer[buffer_length]; + while (fgets(buffer, buffer_length, fp)) { + printf("%s", buffer); + } + fclose(fp); +} + +void command_set(char *filepath, int value) +{ + if (setuid(0)) { + fprintf(stderr, "Cannot set root permissions via setuid(0).\n"); + exit(EXIT_FAILURE); + } + + FILE *fp = fopen(filepath, "w+"); + if (fp == NULL) { + fprintf(stderr, "Cannot open file '%s' for writing.\n", filepath); + exit(EXIT_FAILURE); + } + fprintf(fp, "%d\n", value); + fclose(fp); +} + +int main(int argc, char *argv[]) +{ + if (argc < 1) { + print_usage_and_fail(); + } + argv0 = argv[0]; + if (argc < 3) { + print_usage_and_fail(); + } + char *command = argv[1]; + char *led = argv[2]; + if (strcmp(led, "red") != 0 + && strcmp(led, "blue") != 0 + && strcmp(led, "green") != 0 + && strcmp(led, "flash")) { + print_usage_and_fail(); + } + char *type = "indicator"; + if (strcmp(led, "flash") == 0) { + led = "white"; + type = "flash"; + } + char filename[255]; + sprintf(filename, led_file_template, led, type); + if ((strcmp(command, "get") == 0) && (argc == 3)) { + command_get(filename); + } else if ((strcmp(command, "set") == 0) && (argc == 4)) { + int value = atoi(argv[3]); + if (value < 0 || value > 255) { + print_usage_and_fail(); + } + command_set(filename, value); + } else { + print_usage_and_fail(); + } + exit(EXIT_SUCCESS); +}