lw12/lw12ctl.c

229 lines
6.1 KiB
C
Raw Normal View History

2017-08-27 18:09:01 +02:00
/*
* lw12ctl.c
* Copyright (C) 2017 jpk <jpk@thor>
*
* Distributed under terms of the MIT license.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
2017-08-27 19:59:23 +02:00
#include <readline/readline.h>
2017-10-30 18:44:50 +01:00
#include <readline/history.h>
2017-08-27 19:59:23 +02:00
2017-08-27 18:09:01 +02:00
#include "lw12.h"
2017-08-27 19:59:23 +02:00
#define DebugPrintPos fprintf(stderr, "%s:%d\n", __FILE__, __LINE__)
2017-08-27 18:09:01 +02:00
2017-08-27 19:59:23 +02:00
int exit_interactive_session = 0;
int sockfd = 0;
struct sockaddr_in server_addr;
2017-10-30 18:45:36 +01:00
static void help_lw12_cmd_light() {
printf("Not enough parameters, choices are:\n");
printf(" on\n");
printf(" off\n");
printf(" set <color> <value>\n\n");
printf("Color:\n------\nred\ngreen\nblue\nrgb\n\n"
"The colors red, green and blue require one additional\n"
"parameter as number between 0 - 255. The `rgb` value\n"
"has to be given in #RRGGBB hex format.\n");
}
2017-08-27 19:59:23 +02:00
static int lw12_cmd_light(int argc, char *argv[]) {
if (argc == 0) {
2017-10-30 18:45:36 +01:00
help_lw12_cmd_light();
return 1;
2017-08-27 19:59:23 +02:00
}
if (strncasecmp(argv[0], "on", strlen(argv[0])) == 0) {
lw12_sendcmd(sockfd, &server_addr, (char *)LIGHTS_ON);
lw12_sendcmd(sockfd, &server_addr, (char *)LIGHTS_INIT);
} else if (strncasecmp(argv[0], "off", strlen(argv[0])) == 0) {
lw12_sendcmd(sockfd, &server_addr, (char *)LIGHTS_OFF);
2017-10-30 18:45:36 +01:00
} else if (strncasecmp(argv[0], "help", strlen(argv[0])) == 0) {
help_lw12_cmd_light();
return 1;
2017-08-27 19:59:23 +02:00
} else if (strncasecmp(argv[0], "set", strlen(argv[0])) == 0) {
if (argc < 3) {
2017-08-28 19:08:19 +02:00
printf("Not enough parameters, usage:\n"
" - set <color> <value>\n\b");
2017-08-27 19:59:23 +02:00
return 1;
}
// todo set color
2017-08-28 19:08:19 +02:00
unsigned char cmd[LW12_CMD_LENGTH];
2017-08-27 19:59:23 +02:00
// last char gets not copied?!
2017-08-28 19:08:19 +02:00
strncpy((char *)cmd, LIGHT_COLOR, LW12_CMD_LENGTH);
2017-08-27 19:59:23 +02:00
2017-08-28 19:08:19 +02:00
if (strncasecmp(argv[1], "red", strlen(argv[1])) == 0) {
uint8_t colorvalue = (uint8_t)atoi(argv[2]);
cmd[4] = (char)colorvalue;
} else if (strncasecmp(argv[1], "green", strlen(argv[1])) == 0) {
uint8_t colorvalue = (uint8_t)atoi(argv[2]);
cmd[5] = (char)colorvalue;
} else if (strncasecmp(argv[1], "blue", strlen(argv[1])) == 0) {
uint8_t colorvalue = (uint8_t)atoi(argv[2]);
cmd[6] = (char)colorvalue;
} else if (strncasecmp(argv[1], "rgb", strlen(argv[1])) == 0) {
if (strlen(argv[2]) != 7) {
printf("Invalid RGB value. Example: #ff138a\n");
return 1;
}
char *pos = argv[2];
if (*pos == '#')
pos++;
int colorvalue = (int)strtol(pos, 0, 16);
// exchange byte order to match RR GG BB
colorvalue = (colorvalue & 0x000000ff) << 16
| (colorvalue & 0x00ff0000) >> 16
| (colorvalue & 0x0000ff00);
memcpy(cmd+4, &colorvalue, 4);
} else {
2017-08-27 19:59:23 +02:00
printf("Unknown color selected, use: red, green or blue\n");
return 1;
}
// last char gets not copied?!
cmd[LW12_CMD_LENGTH-1] = '\xef';
lw12_sendcmd(sockfd, &server_addr, (char *)cmd);
2017-10-30 18:45:36 +01:00
} else {
printf("What?!\n");
2017-08-27 19:59:23 +02:00
}
return 0;
}
static int lw12_cmd_exit(int argc, char *argv[]) {
exit_interactive_session = 1;
return 0;
}
struct lw12_command {
const char *cmd;
int (*handler)(int argc, char *argv[]);
const char *usage;
};
2017-08-27 18:09:01 +02:00
2017-08-27 19:59:23 +02:00
static struct lw12_command lw12_commands[] = {
{"light", lw12_cmd_light,
"Control the LED stripe. Turn it on/off and change the colors" },
{"exit", lw12_cmd_exit,
"Exit program"},
{"quit", lw12_cmd_exit,
"Exit program"}
};
2017-08-27 18:09:01 +02:00
2017-08-27 19:59:23 +02:00
int parse_commands(int argc, char *argv[]) {
struct lw12_command *cmd, *match = NULL;
int count = 0;
int ret = 0;
2017-08-27 18:09:01 +02:00
2017-10-30 17:34:17 +01:00
if (argc < 1)
return 1;
2017-08-27 19:59:23 +02:00
cmd = lw12_commands;
while (cmd->cmd) {
2017-10-30 17:34:17 +01:00
if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
2017-08-27 19:59:23 +02:00
match = cmd;
// nessecary?
if (strcasecmp(cmd->cmd, argv[0]) == 0) {
count = 1;
break;
}
count++;
}
cmd++;
}
if (count > 1) {
printf("Ambiguous commnd '%s'; possible commands:", argv[0]);
cmd = lw12_commands;
while (cmd->cmd) {
if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
printf(" %s", cmd->cmd);
}
cmd++;
}
printf("\n");
ret = 1;
} else if (count == 0) {
printf("Unknown command '%s'\n", argv[0]);
ret = 1;
} else {
ret = match->handler(argc - 1, &argv[1]);
}
return ret;
}
void cmd_loop() {
#define max_args 10
#define buf_size 256
2017-10-30 18:44:50 +01:00
char *cmd, *cmd_start;
2017-08-27 19:59:23 +02:00
char *pos;
char *argv[max_args];
int argc;
do {
cmd = readline("> ");
2017-11-19 19:17:07 +01:00
add_history(cmd);
2017-08-27 19:59:23 +02:00
if (cmd == NULL)
break;
2017-10-30 18:44:50 +01:00
cmd_start = pos = cmd;
2017-08-27 19:59:23 +02:00
while (*pos != '\0') {
// convert \n to separate argument
if (*pos == '\n') {
*pos = '\0';
break;
}
pos++;
}
argc = 0;
pos = cmd;
// count number of arguments
for (;;) {
// ignore spaces in the beginning
while (*pos == ' ')
pos++;
if (*pos == '\0')
break;
argv[argc] = pos;
argc++;
if (argc == max_args)
break;
// string arguments
if (*pos == '"') {
char *pos2 = strrchr(pos, '"');
if (pos2)
pos = pos2 + 1;
}
2017-08-28 19:37:16 +02:00
while (*pos != '\0' && *pos != ' ')
2017-08-27 19:59:23 +02:00
pos++;
if (*pos == ' ')
*pos++ = '\0';
}
parse_commands(argc, argv);
2017-10-30 18:44:50 +01:00
free(cmd);
2017-08-27 19:59:23 +02:00
} while (!exit_interactive_session);
}
int main() {
char serverip[] = "192.168.178.24";
uint16_t serverport = 5000;
2017-10-30 18:44:50 +01:00
rl_bind_key('\t', rl_abort);
2017-08-27 19:59:23 +02:00
lw12_connect(&sockfd, &server_addr, serverport, serverip);
cmd_loop();
2017-08-27 18:09:01 +02:00
close(sockfd);
return 0;
}