aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-05-28 11:28:22 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-05-28 11:28:22 +0200
commit25a4f905a3f93645aee79157f30867b287871163 (patch)
tree3f33d41965595cafe5cc0ae783840ffdd3ca27ba
parentf4868604384908a7477cbb4b544c6ee7aac2a883 (diff)
separate the i2c over tcp from puzzle bus libraries
-rw-r--r--client/CMakeLists.txt4
-rw-r--r--client/cmd.cpp4
-rw-r--r--client/examples/puzbus-hello-world.cpp67
-rw-r--r--client/readme.md12
-rw-r--r--client/sock.cpp12
-rw-r--r--i2ctcp/i2ctcpv1.c (renamed from proto/puzbusv1.c)15
-rw-r--r--i2ctcp/i2ctcpv1.h (renamed from proto/puzbusv1.h)42
-rw-r--r--i2ctcp/include.cmake (renamed from proto/include.cmake)4
l---------i2ctcp/lib (renamed from proto/lib)0
-rw-r--r--main/CMakeLists.txt4
-rw-r--r--main/sock.c12
-rw-r--r--shared/busaddr.h20
-rw-r--r--shared/puzbus.h39
13 files changed, 78 insertions, 157 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 6aa4b4f..73c703d 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -7,7 +7,7 @@ set(CMAKE_BUILD_TYPE Debug)
project(puzzlebox_client C CXX)
-include(../proto/include.cmake)
+include(../i2ctcp/include.cmake)
add_executable(pbc
main.cpp
@@ -19,7 +19,7 @@ add_executable(pbc
)
target_link_libraries(pbc
- puzbus
+ i2ctcp
mpack
readline # this is such a common library that I did not bother adding it as a submodule
)
diff --git a/client/cmd.cpp b/client/cmd.cpp
index 736cf12..a26de13 100644
--- a/client/cmd.cpp
+++ b/client/cmd.cpp
@@ -3,11 +3,11 @@
#include <string.h>
#include "cmd.h"
-#include "puzbusv1.h"
+#include "i2ctcpv1.h"
#include "sock.h"
#include "parse.h"
-#include "../shared/busaddr.h"
+#include "../shared/puzbus.h"
char* consume_token(char* input, const char* ifs) {
strtok(input, ifs);
diff --git a/client/examples/puzbus-hello-world.cpp b/client/examples/puzbus-hello-world.cpp
deleted file mode 100644
index dcc965b..0000000
--- a/client/examples/puzbus-hello-world.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <unistd.h>
-
-#include "puzbusv1.h"
-
-int send_message() {
- const char* data = "Test message data!";
- struct pb_msg output = {
- .addr = 0x39,
- .data = (char*) data,
- .length = strlen(data),
- };
-
- char* packed;
- size_t size;
- if (!pb_write(&output, &packed, &size)) {
- printf("error writing!\n");
- return EXIT_FAILURE;
- }
-
- fwrite(packed, sizeof(packed[0]), size, stdout);
- fflush(stdout);
-
- return EXIT_SUCCESS;
-}
-
-int read_message() {
- freopen(NULL, "rb", stdin); // allow binary on stdin
- struct pb_msg input;
-
- char buf[4]; // extremely small buffer to test chunked message parsing
- size_t bytes = 0;
-
- while ((bytes = fread(buf, sizeof(buf[0]), sizeof(buf), stdin)) > 0) {
- int ret = pb_read(&input, buf, bytes);
-
- // header read error
- if (ret < 0) {
- printf("error reading!\n");
- return EXIT_FAILURE;
- }
-
- // continue reading if more bytes needed...
- if (ret > 0) continue;
-
- // message read completely!
- printf("address: 0x%02x\n", input.addr);
- printf("data: \"%.*s\"\n", input.length, input.data);
- free(input.data);
- return EXIT_SUCCESS;
- }
-
- // if we reach this point, data was read but it did not contain a complete
- // message, and is thus considered a failure
- return EXIT_FAILURE;
-}
-
-int main() {
- if (!isatty(fileno(stdout))) return send_message();
- if (!isatty(fileno(stdin))) return read_message();
-
- printf("please pipe some data in or out to use this program\n");
- return EXIT_SUCCESS;
-}
-
diff --git a/client/readme.md b/client/readme.md
index 98cd853..1b4cc34 100644
--- a/client/readme.md
+++ b/client/readme.md
@@ -1,17 +1,5 @@
# puzzle box client
-goal (in order of implementation):
-```
-(pbc) help
- exit exit pbc
- test send a test puzbus message
- help show this help
- send <addr> <data> [debug] send raw message
- status show global puzzle box state (main controller state)
- reset reset entire game state
- ls list connected puzzle modules
-```
-
## Send data
```
diff --git a/client/sock.cpp b/client/sock.cpp
index f967f64..2d5787d 100644
--- a/client/sock.cpp
+++ b/client/sock.cpp
@@ -10,7 +10,7 @@
#include <thread>
-#include "puzbusv1.h"
+#include "i2ctcpv1.h"
#include "sock.h"
#include "rl.h"
@@ -72,7 +72,7 @@ void PBSocket::send(const char * buf, size_t buf_sz) {
}
void PBSocket::sock_task() {
- struct pb_msg input;
+ i2ctcp_msg_t input;
while(1) {
char buf[80];
@@ -86,11 +86,11 @@ void PBSocket::sock_task() {
// skip empty frames
if (bytes == 0) continue;
- int ret = pb_read(&input, buf, bytes);
+ int ret = i2ctcp_read(&input, buf, bytes);
// header read error
if (ret < 0) {
- rl_printf("pb_read error!\n");
+ rl_printf("i2ctcp_read error!\n");
break;
}
@@ -106,7 +106,7 @@ void PBSocket::sock_task() {
}
void i2c_send(uint16_t addr, const char * data, size_t data_size) {
- struct pb_msg msg = {
+ i2ctcp_msg_t msg = {
.addr = addr,
.data = (char *) data,
.length = data_size,
@@ -114,7 +114,7 @@ void i2c_send(uint16_t addr, const char * data, size_t data_size) {
char* packed;
size_t size;
- if (!pb_write(&msg, &packed, &size)) return;
+ if (!i2ctcp_write(&msg, &packed, &size)) return;
sock->send(packed, size);
}
diff --git a/proto/puzbusv1.c b/i2ctcp/i2ctcpv1.c
index 73deda5..36a5dbd 100644
--- a/proto/puzbusv1.c
+++ b/i2ctcp/i2ctcpv1.c
@@ -3,11 +3,10 @@
// MIN() macro
#include <sys/param.h>
-// TODO: check if this works on pico as well
-#include "puzbusv1.h"
+#include "i2ctcpv1.h"
-int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz) {
+int i2ctcp_read(i2ctcp_msg_t * 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);
@@ -17,9 +16,9 @@ int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz) {
// 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.
- // This is a highly unlikely scenario, as pb_read is called for each chunk
- // of a TCP frame, and frames (should) include only one puzzle bus message.
- // The check here is kind of optional.
+ // This is a highly unlikely scenario, as i2ctcp_read is called for each
+ // chunk of a TCP frame, and frames (should) include only one puzzle bus
+ // message. The check here is kind of optional.
if (buf_sz < 4) return -1;
target->addr = mpack_expect_u16(&reader);
@@ -38,11 +37,11 @@ int pb_read(struct pb_msg * target, const char * buf, size_t buf_sz) {
return target->_rdata;
}
-void pb_read_reset(struct pb_msg * target) {
+void i2ctcp_read_reset(i2ctcp_msg_t * target) {
target->_rdata = 0;
}
-bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz) {
+bool i2ctcp_write(const i2ctcp_msg_t * 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/i2ctcp/i2ctcpv1.h
index 9f4f8e5..799b668 100644
--- a/proto/puzbusv1.h
+++ b/i2ctcp/i2ctcpv1.h
@@ -7,20 +7,21 @@
extern "C" {
#endif
-/** \brief Puzzle bus message (v1) */
-struct pb_msg {
+/** \brief I2C over TCP message (v1) */
+struct i2ctcp_msg {
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
};
+typedef struct i2ctcp_msg i2ctcp_msg_t;
/**
* \brief Read chunk of input stream, and store resulting message in \p target
*
* This function is called for each chunk of data from an input stream, and
* will parse the next puzzle bus message into \p target. The input stream is
- * assumed to only contain messages encoded by \p pb_write()
+ * assumed to only contain messages encoded by \p i2ctcp_write()
*
* \param target pointer to struct that will contain the finished message data
* \param buf pointer to input stream data chunk
@@ -34,24 +35,24 @@ 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, const char * buf, size_t buf_sz);
+int i2ctcp_read(i2ctcp_msg_t * target, const char * buf, size_t buf_sz);
/**
* \brief reset the remaining message data counter
*
- * Calling this function has the effect of forcing \c pb_read() to parse the
- * next buffer chunk as the start of a new message. This function may be called
- * before reading a TCP frame's data to mitigate any synchronization issues
- * arising from earlier corrupt or otherwise malformed messages.
+ * Calling this function has the effect of forcing \c i2ctcp_read() to parse
+ * the next buffer chunk as the start of a new message. This function may be
+ * called before reading a TCP frame's data to mitigate any synchronization
+ * issues arising from earlier corrupt or otherwise malformed messages.
*/
-void pb_read_reset(struct pb_msg * target);
+void i2ctcp_read_reset(i2ctcp_msg_t * target);
/**
* \brief Allocate and write a msgpack-formatted message to \p buf
*
* This function allocates a buffer large enough to fit the message specified
* in \p target, and encodes the data in \p target in a format that can be
- * decoded later using \p pb_read()
+ * decoded later using \p i2ctcp_read()
*
* \param target pointer to struct that contains the message data
* \param buf pointer to \c char* that will contain the formatted message
@@ -62,26 +63,7 @@ void pb_read_reset(struct pb_msg * target);
*
* \note the pointer stored in \p buf must be `free()`d by the caller afterwards
*/
-bool pb_write(const struct pb_msg * target, char ** buf, size_t * buf_sz);
-
-/**
- * \brief I^2^C puzzle bus command types
- *
- * The first byte of a puzzle bus message's data indicates the command type.
- */
-enum pb_cmd {
- PB_CMD_READ, //!< read a puzzle module property
- PB_CMD_WRITE, //!< write to a puzzle module property
- // PB_CMD_UPDATE, //!< request an update
-};
-
-/** \brief Puzzle bus global states */
-enum pb_global_state {
- PB_GS_NOINIT, //!< uninitialized (only used by puzzle modules)
- PB_GS_IDLE, //!< puzzle not started yet
- PB_GS_PLAYING, //!< puzzle actively being solved
- PB_GS_SOLVED, //!< puzzle completed
-};
+bool i2ctcp_write(const i2ctcp_msg_t * target, char ** buf, size_t * buf_sz);
#ifdef __cplusplus
}
diff --git a/proto/include.cmake b/i2ctcp/include.cmake
index ac1305e..d755b57 100644
--- a/proto/include.cmake
+++ b/i2ctcp/include.cmake
@@ -1,6 +1,6 @@
include_directories(${CMAKE_CURRENT_LIST_DIR})
-add_library(puzbus STATIC
- ${CMAKE_CURRENT_LIST_DIR}/puzbusv1.c
+add_library(i2ctcp STATIC
+ ${CMAKE_CURRENT_LIST_DIR}/i2ctcpv1.c
)
# mpack
diff --git a/proto/lib b/i2ctcp/lib
index dc598c5..dc598c5 120000
--- a/proto/lib
+++ b/i2ctcp/lib
diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt
index 30685a4..6390d7c 100644
--- a/main/CMakeLists.txt
+++ b/main/CMakeLists.txt
@@ -7,7 +7,7 @@ set(PICO_BOARD pico_w)
include(lib/pico-sdk/pico_sdk_init.cmake)
include(lib/FreeRTOS-Kernel/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake)
-include(../proto/include.cmake)
+include(../i2ctcp/include.cmake)
project(puzzlebox_main C CXX ASM)
@@ -33,7 +33,7 @@ target_link_libraries(main
hardware_i2c
FreeRTOS-Kernel
FreeRTOS-Kernel-Heap4
- puzbus
+ i2ctcp
mpack
)
diff --git a/main/sock.c b/main/sock.c
index 4f50981..fe932bb 100644
--- a/main/sock.c
+++ b/main/sock.c
@@ -7,16 +7,16 @@
#include "init.h"
#include "config.h"
-#include "puzbusv1.h"
+#include "i2ctcpv1.h"
#include "sock.h"
struct netconn* current_connection = NULL;
-struct pb_msg recv_msg;
+i2ctcp_msg_t recv_msg;
void i2c_send(uint16_t addr, const char * data, size_t data_size) {
if (current_connection == NULL) return;
- struct pb_msg send_msg = {
+ i2ctcp_msg_t send_msg = {
.addr = addr,
.data = (char *) data,
.length = data_size,
@@ -25,7 +25,7 @@ void i2c_send(uint16_t addr, const char * data, size_t data_size) {
char * buf;
size_t buf_sz;
- if (!pb_write(&send_msg, &buf, &buf_sz)) return;
+ if (!i2ctcp_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
@@ -47,7 +47,7 @@ void i2c_recv(uint16_t addr, const char * data, size_t data_size) {
}
void recv_handler(struct netconn* conn, struct netbuf* buf) {
- pb_read_reset(&recv_msg);
+ i2ctcp_read_reset(&recv_msg);
do {
char* data;
@@ -55,7 +55,7 @@ void recv_handler(struct netconn* conn, struct netbuf* buf) {
netbuf_data(buf, (void**)&data, &len);
// continue early if more data is needed to complete message
- if (!pb_read(&recv_msg, data, len)) continue;
+ if (!i2ctcp_read(&recv_msg, data, len)) continue;
// forward received message to puzzle bus
i2c_recv(recv_msg.addr, recv_msg.data, recv_msg.length);
diff --git a/shared/busaddr.h b/shared/busaddr.h
deleted file mode 100644
index 5879afe..0000000
--- a/shared/busaddr.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-/** \file bus address reference */
-
-// Adafruit NeoTrellis modules
-#define BUSADDR_ADA_NEO_1 0x2E
-#define BUSADDR_ADA_NEO_2 0x2F
-#define BUSADDR_ADA_NEO_3 0x30
-#define BUSADDR_ADA_NEO_4 0x32
-
-// TODO: ???
-#define BUSADDR_MOD_NEOTRELLIS 0
-#define BUSADDR_MOD_SOFTWARE 0
-#define BUSADDR_MOD_HARDWARE 0
-#define BUSADDR_MOD_VAULT 0
-#define BUSADDR_MOD_AUTOMATION 0
-
-// main controller
-#define BUSADDR_MAIN 0x00
-
diff --git a/shared/puzbus.h b/shared/puzbus.h
new file mode 100644
index 0000000..59a8867
--- /dev/null
+++ b/shared/puzbus.h
@@ -0,0 +1,39 @@
+#pragma once
+
+/** \file bus address reference */
+
+// Adafruit NeoTrellis modules
+#define BUSADDR_ADA_NEO_1 0x2E
+#define BUSADDR_ADA_NEO_2 0x2F
+#define BUSADDR_ADA_NEO_3 0x30
+#define BUSADDR_ADA_NEO_4 0x32
+
+// TODO: ???
+#define BUSADDR_MOD_NEOTRELLIS 0
+#define BUSADDR_MOD_SOFTWARE 0
+#define BUSADDR_MOD_HARDWARE 0
+#define BUSADDR_MOD_VAULT 0
+#define BUSADDR_MOD_AUTOMATION 0
+
+// main controller
+#define BUSADDR_MAIN 0x00
+
+/**
+ * \brief puzzle bus command types
+ *
+ * The first byte of a puzzle bus message's data indicates the command type.
+ */
+enum pb_cmd {
+ PB_CMD_READ, //!< read a puzzle module property
+ PB_CMD_WRITE, //!< write to a puzzle module property
+ // PB_CMD_UPDATE, //!< request an update
+};
+
+/** \brief Puzzle bus global states */
+enum pb_global_state {
+ PB_GS_NOINIT, //!< uninitialized (only used by puzzle modules)
+ PB_GS_IDLE, //!< puzzle not started yet
+ PB_GS_PLAYING, //!< puzzle actively being solved
+ PB_GS_SOLVED, //!< puzzle completed
+};
+