aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/CMakeLists.txt16
-rw-r--r--client/i2c.cpp53
-rw-r--r--client/i2c.h16
-rw-r--r--client/sock.cpp2
4 files changed, 64 insertions, 23 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 8c0dcf3..8d15e50 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -10,7 +10,6 @@ add_compile_definitions(DEBUG)
project(pbc C CXX)
-add_subdirectory(lib/mpack)
add_subdirectory(lib/i2ctcp)
add_subdirectory(lib/pbdrv)
include(lib/pbdrv/ext/stdlib/include.cmake)
@@ -24,12 +23,19 @@ add_executable(pbc
xxd.c
i2c.cpp
mod.c
- )
+)
target_link_libraries(pbc
i2ctcp
- mpack
- readline # this is such a common library that I did not bother adding it as a submodule
+
+ # this is such a common library that I did not bother adding it as a submodule
+ readline
+
+ # pbdrv-mod is used instead of pbdrv because the client generates messages
+ # that are blindly forwarded by the main controller. The message routing
+ # logic from pbdrv-mod is not used as the client is not a puzzle module, but
+ # it still uses the same PB_MOD_ADDR as the main controller to impersonate
+ # the main controller.
pbdrv-mod
- )
+)
diff --git a/client/i2c.cpp b/client/i2c.cpp
index c8b2dc8..18be4bc 100644
--- a/client/i2c.cpp
+++ b/client/i2c.cpp
@@ -7,10 +7,18 @@
#include "xxd.h"
#include "pb.h"
+#include "pb-buf.h"
+#include "pb-msg.h"
#include "pb-types.h"
+#include "pb-mod.h"
+#ifdef DEBUG
bool i2c_dump_send = true;
bool i2c_dump_recv = true;
+#else
+bool i2c_dump_send = false;
+bool i2c_dump_recv = false;
+#endif
void i2c_send(uint16_t addr, const char * data, size_t data_size) {
i2ctcp_msg_t msg = {
@@ -24,20 +32,43 @@ void i2c_send(uint16_t addr, const char * data, size_t data_size) {
if (!i2ctcp_write(&msg, &packed, &size)) return;
sock->send(packed, size);
- if (i2c_dump_send) {
- printf("[%s] addr(0x%02x) data(0x%02lx):\n", __FUNCTION__, addr, data_size);
- xxd(data, data_size);
- }
free(packed);
}
-void i2c_recv(const char * data, size_t data_size) {
- if (i2c_dump_recv) {
- _rl_printf_start();
- printf("[%s] data(0x%02lx):\n", __FUNCTION__, data_size);
- xxd(data, data_size);
- _rl_printf_stop();
- }
+void i2c_dump(const i2ctcp_msg_t * msg) {
+ pb_buf_t buf = {
+ .data = (char *) msg->data,
+ .size = msg->length,
+ };
+ pb_msg_t * pb_msg = pb_msg_read(&buf);
+
+ // ignore invalid messages
+ if (msg == NULL) return;
+ // NOTE: I feel like this check is OK to do because the main controller isn't
+ // supposed to be written to by I2C controllers that aren't puzzle modules.
+ // I2C doesn't tell the receiver *who's* currently addressing it, which means
+ // we have to assume all messages written to the main controller are puzzle
+ // bus messages, and use the puzzle bus message to get the sender's address.
+ i2c_addr_t sender, receiver;
+ sender = receiver = pb_msg->sender;
+
+ bool send = sender == PB_MOD_ADDR; // = PB_ADDR_MOD_MAIN
+
+ if (send) receiver = msg->addr;
+ else receiver = PB_MOD_ADDR;
+
+ pb_msg_free(pb_msg);
+
+ if (send && !i2c_dump_send) return;
+ if (!send && !i2c_dump_recv) return;
+
+ _rl_printf_start();
+
+ const char * direction = send ? "send" : "recv";
+ printf("[I2C %s] 0x%02x -> 0x%02x data(0x%02lx):\n", direction, sender, receiver, msg->length);
+ xxd(msg->data, msg->length);
+
+ _rl_printf_stop();
}
diff --git a/client/i2c.h b/client/i2c.h
index d2cfa9a..538624a 100644
--- a/client/i2c.h
+++ b/client/i2c.h
@@ -3,6 +3,8 @@
#include <stdint.h>
#include <stddef.h>
+#include "i2ctcpv1.h"
+
/**
* \ingroup pbc
* \defgroup pbc_i2c I2C
@@ -22,14 +24,16 @@
*/
void i2c_send(uint16_t addr, const char * data, size_t data_size);
/**
- * \brief Fake I2C receive handler
+ * \brief Handle received (main -> client) I2C messages
*
- * This function is called for I2C messages received by the main controller and
- * forwarded to \ref pbc.
+ * This function is called for I2C messages both sent and received by the main
+ * controller. This function tries to distinguish between sent/received
+ * messages by parsing the message data as a puzzle bus message and checking if
+ * the msg->sender field is equal to the main controller bus address.
*
- * \param data Received data
- * \param data_size size of \p data
+ * \param msg Transferred message
*/
-void i2c_recv(const char * data, size_t data_size);
+void i2c_dump(const i2ctcp_msg_t * msg);
/// \}
+
diff --git a/client/sock.cpp b/client/sock.cpp
index c292d6a..c123411 100644
--- a/client/sock.cpp
+++ b/client/sock.cpp
@@ -99,7 +99,7 @@ void PBSocket::sock_task() {
if (ret > 0) continue;
// message read completely!
- i2c_recv(input.data, input.length);
+ i2c_dump(&input);
free(input.data);
}