diff --git a/CMakeLists.txt b/CMakeLists.txt index 3eef982..468dd73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,3 +8,4 @@ add_definitions('-Wall') add_library (lw12 lw12.c) add_executable (lw12ctl lw12.c lw12ctl.c) +target_link_libraries (lw12ctl readline) diff --git a/lw12ctl.c b/lw12ctl.c index 7eee40d..0da6221 100644 --- a/lw12ctl.c +++ b/lw12ctl.c @@ -10,23 +10,195 @@ #include #include +#include + #include "lw12.h" -int main() { - int sockfd = 0; - struct sockaddr_in server_addr; +#define DebugPrintPos fprintf(stderr, "%s:%d\n", __FILE__, __LINE__) + +int exit_interactive_session = 0; +int sockfd = 0; +struct sockaddr_in server_addr; + + +static int lw12_cmd_light(int argc, char *argv[]) { + if (argc == 0) { + printf("Not enough parameters, choices are:\n"); + printf(" on - turn the LED stripe on\n"); + printf(" off - turn the LED stripe off\n"); + printf(" set " + " - set a color value (e.g. 'light set red 244')\n"); + } + 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); + } else if (strncasecmp(argv[0], "set", strlen(argv[0])) == 0) { + if (argc < 3) { + printf("Not enough parameters, usage:\n"); + printf("set " + " - set a color value (e.g. 'light set red 244')\n"); + return 1; + } + + // todo set color + char cmd[LW12_CMD_LENGTH]; + // last char gets not copied?! + strncpy(cmd, LIGHT_COLOR, LW12_CMD_LENGTH); + + int pos; + if (strncasecmp(argv[1], "red", strlen(argv[1])) == 0) + pos = 0; + else if (strncasecmp(argv[1], "green", strlen(argv[1])) == 0) + pos = 1; + else if (strncasecmp(argv[1], "blue", strlen(argv[1])) == 0) + pos = 2; + else { + printf("Unknown color selected, use: red, green or blue\n"); + return 1; + } + uint8_t colorvalue = (uint8_t)atoi(argv[2]); + cmd[4 + pos] = (char)colorvalue; + // last char gets not copied?! + cmd[LW12_CMD_LENGTH-1] = '\xef'; + lw12_sendcmd(sockfd, &server_addr, (char *)cmd); + } + return 0; +} + +static int lw12_cmd_exit(int argc, char *argv[]) { + exit_interactive_session = 1; + return 0; +} + +static int lw12_cmd_dummy(int argc, char *argv[]) { + return 1; +} + +struct lw12_command { + const char *cmd; + int (*handler)(int argc, char *argv[]); + const char *usage; +}; + +static struct lw12_command lw12_commands[] = { + {"light", lw12_cmd_light, + "Control the LED stripe. Turn it on/off and change the colors" }, + {"foobar", lw12_cmd_dummy, + "Exit program"}, + {"foobaz", lw12_cmd_dummy, + "Exit program"}, + {"exit", lw12_cmd_exit, + "Exit program"}, + {"quit", lw12_cmd_exit, + "Exit program"} +}; + +int parse_commands(int argc, char *argv[]) { + struct lw12_command *cmd, *match = NULL; + int count = 0; + int ret = 0; + + cmd = lw12_commands; + while (cmd->cmd) { + if(strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) { + 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 + char cmdbuf[buf_size]; + char *cmd; + char *pos; + char *argv[max_args]; + int argc; + + do { + cmd = readline("> "); + if (cmd == NULL) + break; + + pos = cmd; + 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; + } + while (*pos != '\0' & *pos != ' ') + pos++; + if (*pos == ' ') + *pos++ = '\0'; + } + + parse_commands(argc, argv); + + if (cmd != cmdbuf) + free(cmd); + + } while (!exit_interactive_session); +} + +int main() { char serverip[] = "192.168.178.24"; uint16_t serverport = 5000; lw12_connect(&sockfd, &server_addr, serverport, serverip); - lw12_sendcmd(sockfd, &server_addr, (char *)LIGHTS_ON); - lw12_sendcmd(sockfd, &server_addr, (char *)LIGHTS_INIT); - - usleep(2000000); - - lw12_sendcmd(sockfd, &server_addr, (char *)LIGHTS_OFF); - + cmd_loop(); close(sockfd); return 0;