aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2022-12-12 13:57:33 +0100
committerlonkaars <loek@pipeframe.xyz>2022-12-12 13:57:33 +0100
commit61dd8a5ee66734dfd53ee9be725c9e71fd8d5414 (patch)
treeda896421d93baa3a80a7c6ebb3a16fc25138516f
parent8c21a929d06ed108b0e64f3892d036cd4cd67e51 (diff)
implement DYN_MEMBER_SIZEOF macro correctly and implement cd_cmd_response_sizeof
-rw-r--r--confui/mainwindow.cpp5
-rw-r--r--confui/serial.h2
-rw-r--r--shared/bin.c8
-rw-r--r--shared/bin.h16
-rw-r--r--shared/protocol-tests/ping-response.binbin0 -> 10 bytes
-rw-r--r--shared/protocol.c32
6 files changed, 56 insertions, 7 deletions
diff --git a/confui/mainwindow.cpp b/confui/mainwindow.cpp
index 1fd34c4..b5bbdf0 100644
--- a/confui/mainwindow.cpp
+++ b/confui/mainwindow.cpp
@@ -13,7 +13,10 @@ CDMeshConnector *g_cd_mesh_connector = nullptr;
CDSerialConnector *g_cd_serial = nullptr;
QApplication* g_cd_app = nullptr;
-CDMainWindow::~CDMainWindow() { delete this->mesh_connector; }
+CDMainWindow::~CDMainWindow() {
+ delete g_cd_mesh_connector;
+ delete g_cd_serial;
+}
CDMainWindow::CDMainWindow(QWidget *parent) : QMainWindow(parent) {
g_cd_mesh_connector = new CDMeshConnector();
diff --git a/confui/serial.h b/confui/serial.h
index 22f2542..aa0508f 100644
--- a/confui/serial.h
+++ b/confui/serial.h
@@ -11,7 +11,7 @@ using std::vector;
class CDSerialConnector {
public:
CDSerialConnector();
- ~CDSerialConnector();
+ virtual ~CDSerialConnector();
/** @brief get list of available serial ports */
static vector<string> get_ports();
diff --git a/shared/bin.c b/shared/bin.c
index fdceb30..875d013 100644
--- a/shared/bin.c
+++ b/shared/bin.c
@@ -65,6 +65,14 @@ uint16_t cd_bin_hton16(uint16_t h16) {
uint32_t cd_bin_ntoh32(uint32_t n32) { return cd_bin_hton32(n32); }
uint16_t cd_bin_ntoh16(uint16_t n16) { return cd_bin_hton16(n16); }
+uint32_t cd_bin_ntohd(uint8_t* n, size_t s) { return cd_bin_htond(n, s); }
+
+uint32_t cd_bin_htond(uint8_t* h, size_t s) {
+ if (s == sizeof(uint8_t)) return *h;
+ else if (s == sizeof(uint16_t)) return cd_bin_hton16(*(uint16_t*) h);
+ else if (s == sizeof(uint32_t)) return cd_bin_hton32(*(uint32_t*) h);
+ else return 0;
+}
cd_s_bin *cd_bin_s_alloc(uint16_t bytes, uint8_t *data) {
cd_s_bin *temp = malloc(sizeof(cd_s_bin) + sizeof(uint8_t) * bytes);
diff --git a/shared/bin.h b/shared/bin.h
index 35d2bc4..0e16ec0 100644
--- a/shared/bin.h
+++ b/shared/bin.h
@@ -10,6 +10,7 @@
*/
#include <stdint.h>
+#include <malloc.h>
#ifdef __cplusplus
extern "C" {
@@ -50,6 +51,21 @@ uint32_t cd_bin_ntoh32(uint32_t n32);
/** @brief convert 16-bit value from network (big-endian) to host endian */
uint16_t cd_bin_ntoh16(uint16_t n16);
+/**
+ * @brief convert (8*s)-bit value from network (big-endian) to host endian
+ * (dynamic size)
+ *
+ * @param n pointer to number
+ * @param s size of number in bytes
+ *
+ * @return 32-bit integer regardless of `s`
+ *
+ * this function is exclusively used by the CD_DYN_MEMBER_SIZEOF macro in
+ * shared/protocol.c
+ */
+uint32_t cd_bin_ntohd(uint8_t* n, size_t s);
+uint32_t cd_bin_htond(uint8_t* h, size_t s);
+
/** @brief replace 32-bit value from host endian to network (big-endian) */
void cd_bin_repl_hton32(uint32_t *h32);
/** @brief replace 16-bit value from host endian to network (big-endian) */
diff --git a/shared/protocol-tests/ping-response.bin b/shared/protocol-tests/ping-response.bin
new file mode 100644
index 0000000..6067349
--- /dev/null
+++ b/shared/protocol-tests/ping-response.bin
Binary files differ
diff --git a/shared/protocol.c b/shared/protocol.c
index 474398a..1d66f17 100644
--- a/shared/protocol.c
+++ b/shared/protocol.c
@@ -1,3 +1,5 @@
+#include <stddef.h>
+
#include "protocol.h"
#ifdef __cplusplus
@@ -16,13 +18,33 @@ size_t cd_cmd_sizeof(uint8_t data[CD_SERIAL_READ_BUFFER_SIZE], uint8_t data_leng
return length;
}
-#define CD_DYN_MEMBER_SIZEOF(struct_t, length_byte, trailing_type) \
- sizeof(struct_t) + \
- (data->bytes > length_byte ? (sizeof(trailing_type) * data->data[length_byte]) : 0)
+/**
+ * @brief macro to calculate size of message based on struct with member to
+ * indicate length of dynamic (last) field
+ *
+ * @param data cd_s_bin pointer to currently received data
+ * @param struct_t message struct
+ * @param length_field struct field with dynamic length
+ *
+ * @return size_t with calculated size
+ *
+ * equivalent c code:
+ *
+ * size_t size = sizeof(struct_t);
+ * size_t dyn_member_offset = offsetof(struct_t, length_field);
+ * size_t dyn_member_size = sizeof(((struct_t*)0)->length_field);
+ * if (data->bytes >= (dyn_member_offset + dyn_member_size))
+ * size += cd_bin_ntohd(&data->data[dyn_member_offset], dyn_member_size);
+ * return size;
+ */
+#define CD_DYN_MEMBER_SIZEOF(data, struct_t, length_field) \
+ sizeof(struct_t) + ( \
+ (data->bytes >= (offsetof(struct_t, length_field) + sizeof(((struct_t*)0)->length_field))) ? \
+ (cd_bin_ntohd(&data->data[offsetof(struct_t, length_field)], sizeof(((struct_t*)0)->length_field))) :\
+ 0);
size_t cd_cmd_response_sizeof(cd_s_bin* data) {
- (void) data; // unused variable TODO: implement this
- return 0;
+ return CD_DYN_MEMBER_SIZEOF(data, cd_s_cmd_response, response_size);
}
#ifdef __cplusplus