From db8906d54cd9afbc57f0b40a0d618335c552f704 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Mon, 20 May 2024 13:47:37 +0200 Subject: back-and-forth in C++ w/o netcat --- client/CMakeLists.txt | 2 +- client/main.cpp | 12 ++++++--- client/rl.c | 55 ----------------------------------------- client/rl.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ client/rl.h | 8 ------ client/sock.cpp | 46 +++++++++++++++++++++++++++++++--- client/sock.h | 7 ++++++ 7 files changed, 128 insertions(+), 70 deletions(-) delete mode 100644 client/rl.c create mode 100644 client/rl.cpp diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index e4990d7..cae0111 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -10,7 +10,7 @@ include(../proto/include.cmake) add_executable(main main.cpp - rl.c + rl.cpp sock.cpp ) diff --git a/client/main.cpp b/client/main.cpp index c01dbb5..5c26107 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -6,6 +6,8 @@ #include "rl.h" #include "sock.h" +PBSocket* sock; + int main(int argc, char** argv) { if (argc < 2) { printf("usage: %s addr [port]\n", argv[0]); @@ -17,16 +19,20 @@ int main(int argc, char** argv) { uint16_t port = 9191; if (argc >= 3) port = atoi(argv[2]); - PBSocket sock(addr, port); + sock = new PBSocket(addr, port); try { // connect to TCP socket (automatically spawns thread) - sock.sock_connect(); + sock->sock_connect(); } catch (const std::exception& e) { printf("error: %s\n", e.what()); return EXIT_FAILURE; } // enter main CLI (using GNU readline for comfyness) - return cli_main(); + int ret = cli_main(); + + delete sock; + + return ret; } diff --git a/client/rl.c b/client/rl.c deleted file mode 100644 index fb26057..0000000 --- a/client/rl.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#include "rl.h" - -void rl_printf(const char *fmt, ...) { - // save line - char* saved_line = rl_copy_text(0, rl_end); - int saved_point = rl_point; - int saved_end = rl_end; - - // clear line - rl_save_prompt(); - rl_replace_line("", 0); - rl_redisplay(); - - // printf - va_list args; - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - - // restore line - rl_restore_prompt(); - rl_replace_line(saved_line, 0); - rl_point = saved_point; - rl_end = saved_end; - rl_redisplay(); - - free(saved_line); -} - -int cli_main() { - char* input = NULL; - while (1) { - if (input != NULL) free(input); - input = readline(CLI_PROMPT); - - // exit on ^D or ^C (EOF) - if (input == NULL) return EXIT_SUCCESS; - - // add non-empty line to history - if (*input) add_history(input); - - if (strcmp(input, "exit") == 0) return EXIT_SUCCESS; - } - - return EXIT_SUCCESS; -} - diff --git a/client/rl.cpp b/client/rl.cpp new file mode 100644 index 0000000..32a4df0 --- /dev/null +++ b/client/rl.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +#include +#include + +#include "rl.h" +#include "sock.h" + +void rl_printf(const char *fmt, ...) { + // save line + char* saved_line = rl_copy_text(0, rl_end); + int saved_point = rl_point; + int saved_end = rl_end; + + // clear line + rl_save_prompt(); + rl_replace_line("", 0); + rl_redisplay(); + + // printf + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + // restore line + rl_restore_prompt(); + rl_replace_line(saved_line, 0); + rl_point = saved_point; + rl_end = saved_end; + rl_redisplay(); + + free(saved_line); +} + +void cmd_test() { + const char* data = "Hello world!"; + i2c_send(0x39, (char*) data, strlen(data)); +} + +int cli_main() { + char* input = NULL; + while (1) { + if (input != NULL) free(input); + input = readline(CLI_PROMPT); + + // exit on ^D or ^C (EOF) + if (input == NULL) return EXIT_SUCCESS; + + // add non-empty line to history + if (*input) add_history(input); + + if (strcmp(input, "exit") == 0) return EXIT_SUCCESS; + + if (strcmp(input, "test") == 0) { + cmd_test(); + continue; + } + + printf("unknown command!\n"); + } + + return EXIT_SUCCESS; +} + diff --git a/client/rl.h b/client/rl.h index 313a8fe..503225f 100644 --- a/client/rl.h +++ b/client/rl.h @@ -5,14 +5,6 @@ #define CLI_PROMPT "(" COLOR_BOLD "pbc" COLOR_OFF ") " -#ifdef __cplusplus -extern "C" { -#endif - int cli_main(); void rl_printf(const char *fmt, ...); -#ifdef __cplusplus -} -#endif - diff --git a/client/sock.cpp b/client/sock.cpp index c10fba0..cc18a69 100644 --- a/client/sock.cpp +++ b/client/sock.cpp @@ -10,6 +10,7 @@ #include +#include "puzbusv1.h" #include "sock.h" #include "rl.h" @@ -66,20 +67,59 @@ void PBSocket::sock_close() { _fd = -1; } +void PBSocket::send(char* buf, size_t buf_sz) { + write(_fd, buf, buf_sz); +} + void PBSocket::sock_task() { + struct pb_msg input; + while(1) { char buf[80]; ssize_t bytes = read(_fd, buf, sizeof(buf)); if (bytes == -1) { rl_printf("error: %s (%d)\n", strerror(errno), errno); - sock_close(); break; } - if (bytes > 0) { - rl_printf("received %d bytes\n", bytes); + // skip empty frames + if (bytes == 0) continue; + + int ret = pb_read(&input, buf, bytes); + + // header read error + if (ret < 0) { + rl_printf("pb_read error!\n"); + break; } + + // continue reading if more bytes needed... + if (ret > 0) continue; + + // message read completely! + i2c_recv(input.addr, input.data, input.length); + free(input.data); } + + sock_close(); +} + +void i2c_send(uint16_t addr, char* data, size_t data_size) { + struct pb_msg msg = { + .addr = addr, + .data = data, + .length = data_size, + }; + + char* packed; + size_t size; + if (!pb_write(&msg, &packed, &size)) return; + + sock->send(packed, size); +} + +void i2c_recv(uint16_t addr, char* data, size_t data_size) { + rl_printf("[0x%02x]: %.*s\n", addr, data_size, data); } diff --git a/client/sock.h b/client/sock.h index 0f9a3fc..818ea72 100644 --- a/client/sock.h +++ b/client/sock.h @@ -13,6 +13,8 @@ public: void sock_connect(); + void send(char* buf, size_t buf_sz); + private: void sock_task(); void sock_close(); @@ -26,3 +28,8 @@ private: }; +extern PBSocket* sock; + +void i2c_send(uint16_t addr, char* data, size_t data_size); +void i2c_recv(uint16_t addr, char* data, size_t data_size); + -- cgit v1.2.3