From 2d3ba07806517f0d27b118df761675a05ab98fc7 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sun, 19 May 2024 15:10:46 +0200 Subject: add puzzle bus serializer to main controller application --- main/CMakeLists.txt | 1 + main/sock.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) (limited to 'main') diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index cd90499..90ca8e3 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -31,6 +31,7 @@ target_link_libraries(main pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 + puzbus mpack ) diff --git a/main/sock.c b/main/sock.c index dac62af..705e2eb 100644 --- a/main/sock.c +++ b/main/sock.c @@ -3,19 +3,61 @@ #include #include #include +#include #include "init.h" #include "config.h" +#include "puzbusv1.h" +#include "sock.h" struct netconn* current_connection = NULL; +struct pb_msg recv_msg; -void recv_handler(struct netconn* conn, struct netbuf* buf) { - void *data; - uint16_t len; +void i2c_send(uint16_t addr, char* data, size_t data_size) { + if (current_connection == NULL) return; + + struct pb_msg send_msg = { + .addr = addr, + .data = data, + .length = data_size, + }; + + char* buf; + size_t buf_sz; + + if (!pb_write(&send_msg, &buf, &buf_sz)) return; + + // NOTE: netconn does return an error code, but the data needs to be freed + // whether netconn throws an error or not, so it remains unused + netconn_write(current_connection, buf, buf_sz, NETCONN_COPY); + + free(buf); +} +void i2c_recv(uint16_t addr, char* data, size_t data_size) { + printf("address: 0x%02x\n", addr); + printf("data: \"%.*s\"\n", data_size, data); + + // send message back + char reply[] = "Test message back!"; + i2c_send(0x69, reply, strlen(reply)); + + // TODO: this function should forward the recieved message onto the puzzle + // bus instead of printing/replying +} + +void recv_handler(struct netconn* conn, struct netbuf* buf) { do { - netbuf_data(buf, &data, &len); - printf("got %d bytes!\n", len); + char* data; + uint16_t len; + netbuf_data(buf, (void**)&data, &len); + + // continue early if more data is needed to complete message + if (!pb_read(&recv_msg, data, len)) continue; + + // forward received message to puzzle bus + i2c_recv(recv_msg.addr, recv_msg.data, recv_msg.length); + free(recv_msg.data); } while (netbuf_next(buf) >= 0); netbuf_delete(buf); -- cgit v1.2.3 From 68a5c65f9b0e1df30e9cef490d9b218b2f21f90d Mon Sep 17 00:00:00 2001 From: lonkaars Date: Tue, 21 May 2024 10:30:06 +0200 Subject: clean up puzbusv1 API --- client/sock.cpp | 12 ++++++------ client/sock.h | 13 ++++++------- main/sock.c | 10 ++++++---- main/sock.h | 4 ++-- proto/puzbusv1.c | 33 +++++++++++---------------------- proto/puzbusv1.h | 14 ++++++++------ 6 files changed, 39 insertions(+), 47 deletions(-) (limited to 'main') diff --git a/client/sock.cpp b/client/sock.cpp index cc18a69..f967f64 100644 --- a/client/sock.cpp +++ b/client/sock.cpp @@ -18,7 +18,7 @@ using std::logic_error; using std::thread; PBSocket::PBSocket() { } -PBSocket::PBSocket(char* addr, uint16_t port) : PBSocket() { +PBSocket::PBSocket(const char * addr, uint16_t port) : PBSocket() { set_server(addr, port); } @@ -32,7 +32,7 @@ PBSocket::~PBSocket() { sock_close(); } -void PBSocket::set_server(char* addr, uint16_t port) { +void PBSocket::set_server(const char * addr, uint16_t port) { _addr = addr; _port = port; } @@ -67,7 +67,7 @@ void PBSocket::sock_close() { _fd = -1; } -void PBSocket::send(char* buf, size_t buf_sz) { +void PBSocket::send(const char * buf, size_t buf_sz) { write(_fd, buf, buf_sz); } @@ -105,10 +105,10 @@ void PBSocket::sock_task() { sock_close(); } -void i2c_send(uint16_t addr, char* data, size_t data_size) { +void i2c_send(uint16_t addr, const char * data, size_t data_size) { struct pb_msg msg = { .addr = addr, - .data = data, + .data = (char *) data, .length = data_size, }; @@ -119,7 +119,7 @@ void i2c_send(uint16_t addr, char* data, size_t data_size) { sock->send(packed, size); } -void i2c_recv(uint16_t addr, char* data, size_t data_size) { +void i2c_recv(uint16_t addr, const 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 818ea72..42eba3b 100644 --- a/client/sock.h +++ b/client/sock.h @@ -6,14 +6,14 @@ class PBSocket { public: PBSocket(); - PBSocket(char* addr, uint16_t port); + PBSocket(const char * addr, uint16_t port); virtual ~PBSocket(); - void set_server(char* addr, uint16_t port); + void set_server(const char * addr, uint16_t port); void sock_connect(); - void send(char* buf, size_t buf_sz); + void send(const char * buf, size_t buf_sz); private: void sock_task(); @@ -21,15 +21,14 @@ private: std::thread* _thread = nullptr; - char* _addr = NULL; + const char * _addr = NULL; uint16_t _port = 0; int _fd = -1; - }; 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); +void i2c_send(uint16_t addr, const char * data, size_t data_size); +void i2c_recv(uint16_t addr, const char * data, size_t data_size); diff --git a/main/sock.c b/main/sock.c index 705e2eb..4f50981 100644 --- a/main/sock.c +++ b/main/sock.c @@ -13,16 +13,16 @@ struct netconn* current_connection = NULL; struct pb_msg recv_msg; -void i2c_send(uint16_t addr, char* data, size_t data_size) { +void i2c_send(uint16_t addr, const char * data, size_t data_size) { if (current_connection == NULL) return; struct pb_msg send_msg = { .addr = addr, - .data = data, + .data = (char *) data, .length = data_size, }; - char* buf; + char * buf; size_t buf_sz; if (!pb_write(&send_msg, &buf, &buf_sz)) return; @@ -34,7 +34,7 @@ void i2c_send(uint16_t addr, char* data, size_t data_size) { free(buf); } -void i2c_recv(uint16_t addr, char* data, size_t data_size) { +void i2c_recv(uint16_t addr, const char * data, size_t data_size) { printf("address: 0x%02x\n", addr); printf("data: \"%.*s\"\n", data_size, data); @@ -47,6 +47,8 @@ void i2c_recv(uint16_t addr, char* data, size_t data_size) { } void recv_handler(struct netconn* conn, struct netbuf* buf) { + pb_read_reset(&recv_msg); + do { char* data; uint16_t len; diff --git a/main/sock.h b/main/sock.h index 2a73418..f2db35d 100644 --- a/main/sock.h +++ b/main/sock.h @@ -6,6 +6,6 @@ /** \brief start listening for TCP socket requests */ void serve_task(); -void i2c_send(uint16_t addr, char* data, size_t data_size); -void i2c_recv(uint16_t addr, char* data, size_t data_size); +void i2c_send(uint16_t addr, const char * data, size_t data_size); +void i2c_recv(uint16_t addr, const char * data, size_t data_size); diff --git a/proto/puzbusv1.c b/proto/puzbusv1.c index 3be4939..73deda5 100644 --- a/proto/puzbusv1.c +++ b/proto/puzbusv1.c @@ -7,24 +7,13 @@ #include "puzbusv1.h" -/** - * \brief Remaining bytes to be read to target->data - * - * This is the only variable that needs to persist between buffer blocks. It is - * declared in the global scope to allow resetting using the \c pb_read_reset() - * function. - * - * \note \p rdata may be reset by calling \c pb_read_reset() - */ -static size_t rdata = 0; - -int pb_read(struct pb_msg* target, char* buf, size_t buf_sz) { +int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz) { // a new reader is used per buffer block passed to this function mpack_reader_t reader; mpack_reader_init_data(&reader, buf, buf_sz); // at start of message - if (rdata == 0) { + if (target->_rdata == 0) { // NOTE: The entire start of a message needs to be readable from the buffer // at this point. When target->addr can be read and target->length is past // the end of the current buffer block, this function will crash and burn. @@ -34,26 +23,26 @@ int pb_read(struct pb_msg* target, char* buf, size_t buf_sz) { if (buf_sz < 4) return -1; target->addr = mpack_expect_u16(&reader); - target->length = rdata = mpack_expect_bin(&reader); - target->data = (char*) malloc(target->length); + target->length = target->_rdata = mpack_expect_bin(&reader); + target->data = (char *) malloc(target->length); } // continue reading chunks of target->data until the amount of bytes // specified in target->length - size_t to_read = MIN(mpack_reader_remaining(&reader, NULL), rdata); - char* data = target->data + target->length - rdata; // 'ol pointer arithmetic + size_t to_read = MIN(mpack_reader_remaining(&reader, NULL), target->_rdata); + char * data = target->data + target->length - target->_rdata; mpack_read_bytes(&reader, data, to_read); - rdata -= to_read; + target->_rdata -= to_read; // if rdata = 0, the message was completely read - return rdata; + return target->_rdata; } -void pb_read_reset() { - rdata = 0; +void pb_read_reset(struct pb_msg * target) { + target->_rdata = 0; } -bool pb_write(struct pb_msg* target, char** buf, size_t* buf_sz) { +bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz) { mpack_writer_t writer; mpack_writer_init_growable(&writer, buf, buf_sz); diff --git a/proto/puzbusv1.h b/proto/puzbusv1.h index 95130c9..0985b2b 100644 --- a/proto/puzbusv1.h +++ b/proto/puzbusv1.h @@ -7,10 +7,12 @@ extern "C" { #endif +/** \brief Puzzle bus message (v1) */ struct pb_msg { - uint16_t addr; - char* data; - size_t length; + uint16_t addr; //!< I^2^C address + char * data; //!< message content + size_t length; //!< message size + size_t _rdata; //!< \private remaining bytes to read until message is complete }; /** @@ -32,7 +34,7 @@ struct pb_msg { * the message is not fully parsed. This variable must be `free()`d by the * caller after each complete message to prevent memory leaks. */ -int pb_read(struct pb_msg* target, char* buf, size_t buf_sz); +int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz); /** * \brief reset the remaining message data counter @@ -42,7 +44,7 @@ int pb_read(struct pb_msg* target, char* buf, size_t buf_sz); * before reading a TCP frame's data to mitigate any synchronization issues * arising from earlier corrupt or otherwise malformed messages. */ -void pb_read_reset(); +void pb_read_reset(struct pb_msg * target); /** * \brief Allocate and write a msgpack-formatted message to \p buf @@ -60,7 +62,7 @@ void pb_read_reset(); * * \note the pointer stored in \p buf must be `free()`d by the caller afterwards */ -bool pb_write(struct pb_msg* target, char** buf, size_t* buf_sz); +bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz); #ifdef __cplusplus } -- cgit v1.2.3