diff --git a/serial_link/protocol/transport.c b/serial_link/protocol/transport.c
index 399894ff9..7b2c14950 100644
--- a/serial_link/protocol/transport.c
+++ b/serial_link/protocol/transport.c
@@ -24,10 +24,12 @@ SOFTWARE.
 
 #include "protocol/transport.h"
 
-static uint32_t current_send_frame;
+static remote_object_t* remote_objects;
+static uint32_t num_remote_objects;
 
-void init_transport(void) {
-    current_send_frame = 0;
+void init_transport(remote_object_t* _remote_objects, uint32_t _num_remote_objects) {
+    remote_objects = _remote_objects;
+    num_remote_objects = _num_remote_objects;
 }
 
 void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) {
@@ -35,5 +37,4 @@ void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) {
 }
 
 uint32_t transport_send_frame(uint8_t to, uint8_t* data, uint16_t size) {
-    return ++current_send_frame;
 }
diff --git a/serial_link/protocol/transport.h b/serial_link/protocol/transport.h
index 6f2cf277f..86086b8b8 100644
--- a/serial_link/protocol/transport.h
+++ b/serial_link/protocol/transport.h
@@ -28,63 +28,66 @@ SOFTWARE.
 #include "protocol/triple_buffered_object.h"
 
 #define NUM_SLAVES 8
+#define LOCAL_OBJECT_EXTRA 16
+
+// master -> slave = 1 local(target all), 1 remote object
+// slave -> master = 1 local(target 0), multiple remote objects
+// master -> single slave (multiple local, target id), 1 remote object
+typedef enum {
+    MASTER_TO_ALL_SLAVES,
+    MASTER_TO_SINGLE_SLAVE,
+    SLAVE_TO_MASTER,
+} remote_object_type;
 
 typedef struct {
-    uint16_t element_size;
-    uint16_t buffer_size;
-    uint8_t is_master;
+    remote_object_type object_type;
+    uint16_t object_size;
     uint8_t buffer[] __attribute__((aligned(4)));
 } remote_object_t;
 
-typedef struct {
-    uint16_t element_size;
-    uint8_t destination;
-    uint8_t buffer[] __attribute__((aligned(4)));
-} local_object_t;
+#define REMOTE_OBJECT_SIZE(objectsize) \
+    (sizeof(triple_buffer_object_t) + objectsize * 3)
+#define LOCAL_OBJECT_SIZE(objectsize) \
+    (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3)
 
-#define REMOTE_OBJECT_BUFFER(id, type) \
-typedef struct { \
-    triple_buffer_object_t object; \
-    type buffer[3]; \
-} remote_object_buffer_##id##_t;
-
-#define MASTER_REMOTE_OBJECT(id, type) \
-REMOTE_OBJECT_BUFFER(id, type) \
+#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote) \
 typedef struct { \
     remote_object_t object; \
-    remote_object_buffer_##id##_t buffer; \
-} master_remote_object_##id##_t; \
-master_remote_object_##id##_t remote_object_##id = { \
-     .object = { \
-        .element_size = sizeof(type), \
-        .buffer_size = sizeof(remote_object_buffer_##id##_t), \
-        .is_master = true \
-    }};
+    uint8_t buffer[ \
+        num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + \
+        num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \
+} remote_object_##name##_t;
 
-#define SLAVE_REMOTE_OBJECT(id, type) \
-REMOTE_OBJECT_BUFFER(id, type) \
-typedef struct { \
-    remote_object_t object; \
-    remote_object_buffer_##id##_t buffer[NUM_SLAVES];\
-} slave_remote_object_##id##_t; \
-slave_remote_object_##id##_t remote_object_##id = { \
-     .object = { \
-        .element_size = sizeof(type), \
-        .buffer_size = sizeof(remote_object_buffer_##id##_t), \
-        .is_master = true \
-    }};
+#define MASTER_TO_ALL_SLAVES_OBJECT(name, type) \
+    REMOTE_OBJECT_HELPER(name, type, 1, 1) \
+    remote_object_##name##_t remote_object_##name = { \
+        .object = { \
+            .object_type = MASTER_TO_ALL_SLAVES, \
+            .object_size = sizeof(type), \
+        } \
+    };
 
-#define LOCAL_OBJECT(id, type) \
-typedef struct { \
-    uint32_t element_size; \
-    uint8_t buffer[NUM_SLAVES][sizeof(type) + 16][3]; \
-} remote_object_##id##_t; \
-remote_object_##id##_t remote_object_##id = {.element_size = sizeof(type) + 16};
+#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type) \
+    REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1) \
+    remote_object_##name##_t remote_object_##name = { \
+        .object = { \
+            .object_type = MASTER_TO_SINGLE_SLAVE, \
+            .object_size = sizeof(type), \
+        } \
+    };
 
-#define REMOTE_OBJECT(id) (remote_object_t*)&remote_object_##id
+#define SLAVE_TO_MASTER_OBJECT(name, type) \
+    REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES) \
+    remote_object_##name##_t remote_object_##name = { \
+        .object = { \
+            .object_type = SLAVE_TO_MASTER, \
+            .object_size = sizeof(type), \
+        } \
+    };
 
+#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name
 
-void init_transport(void);
+void init_transport(remote_object_t* remote_objects, uint32_t num_remote_objects);
 void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size);
 uint32_t transport_send_frame(uint8_t to, uint8_t* data, uint16_t size);
 
diff --git a/serial_link/tests/transport_tests.c b/serial_link/tests/transport_tests.c
index f9f5b4773..31e7b2dc7 100644
--- a/serial_link/tests/transport_tests.c
+++ b/serial_link/tests/transport_tests.c
@@ -34,32 +34,21 @@ typedef struct {
     uint32_t test2;
 } test_object2_t;
 
-MASTER_REMOTE_OBJECT(0, test_object1_t);
-SLAVE_REMOTE_OBJECT(1, test_object1_t);
-MASTER_REMOTE_OBJECT(2, test_object2_t);
-SLAVE_REMOTE_OBJECT(3, test_object2_t);
+MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1_t);
+MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1_t);
+SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1_t);
 
-// We want
-// master -> slave = 1 local(target all), 1 remote object
-// slave -> master = 1 local(target 0), multiple remote objects
-// master -> single slave (multiple local, target id), 1 remote object
-
-remote_object_t* remote_objects[] = {
-    REMOTE_OBJECT(0),
-    REMOTE_OBJECT(1),
-    REMOTE_OBJECT(2),
-    REMOTE_OBJECT(3),
+remote_object_t* test_remote_objects[] = {
+    REMOTE_OBJECT(master_to_slave),
+    REMOTE_OBJECT(master_to_single_slave),
+    REMOTE_OBJECT(slave_to_master),
 };
 
 Describe(Transport);
 BeforeEach(Transport) {
-    init_transport();
+    init_transport(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t));
 }
 AfterEach(Transport) {}
 
-Ensure(Transport, packet_number_is_sequential) {
-    assert_that(transport_send_frame(0, NULL, 0), is_equal_to(1));
-    assert_that(transport_send_frame(0, NULL, 0), is_equal_to(2));
-    // It doesn't matter if the destination changes
-    assert_that(transport_send_frame(1, NULL, 0), is_equal_to(3));
+Ensure(Transport, write_to_local_signals_an_event) {
 }