Skip to content

Commit 7ad11a2

Browse files
committed
Initial Husarnet transport using TCP
Signed-off-by: Pablo Garrido <[email protected]>
1 parent cc2863c commit 7ad11a2

File tree

1 file changed

+80
-5
lines changed

1 file changed

+80
-5
lines changed

src/husarnet_transport.cpp

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,98 @@ size_t arduino_husarnet_transport_write(struct uxrCustomTransport *transport,
3535
const uint8_t *buf, size_t len,
3636
uint8_t *errcode) {
3737
(void)errcode;
38-
struct micro_ros_agent_locator *locator =
39-
(struct micro_ros_agent_locator *)transport->args;
4038

41-
Serial1.printf("transport_write:\r\n\tbuf:%s\r\n\tlen:%d\r\n", buf, len);
39+
// As we are using a TCP stream connection we should indicate the size of the message with the first two bytes of the stream.
40+
static uint8_t buffer_size[2];
41+
buffer_size[0] = (uint8_t)(0x00FF & len);
42+
buffer_size[1] = (uint8_t)((0xFF00 & len) >> 8);
43+
size_t sent = client.write(buffer_size, 2);
4244

43-
size_t sent = client.write(buf, len);
45+
// Then we send the payload
46+
if (sent == 2) {
47+
sent = client.write(buf, len);
48+
} else {
49+
sent = 0;
50+
}
4451

4552
return sent;
4653
}
4754

55+
// Sample state machine for receiving data
56+
typedef enum {
57+
STATE_WAIT_FOR_SIZE = 0,
58+
STATE_WAIT_FOR_DATA,
59+
STATE_MESSAGE_AVAILABLE
60+
} husarnet_tcp_states_t;
61+
62+
typedef struct {
63+
uint8_t buffer[UXR_CONFIG_CUSTOM_TRANSPORT_MTU];
64+
65+
uint8_t length_buffer[2];
66+
67+
uint16_t message_size;
68+
uint16_t message_size_received;
69+
70+
husarnet_tcp_states_t state;
71+
} husarnet_tcp_receiver_t;
72+
73+
static husarnet_tcp_receiver_t receiver = {};
74+
75+
void read_tcp_data(husarnet_tcp_receiver_t & r) {
76+
switch(r.state) {
77+
case STATE_WAIT_FOR_SIZE:
78+
if (client.available() >= 2)
79+
{
80+
client.read(r.length_buffer, 2);
81+
r.message_size = (r.length_buffer[0] | (r.length_buffer[1] << 8));
82+
r.message_size_received = 0;
83+
r.state = STATE_WAIT_FOR_DATA;
84+
}
85+
break;
86+
case STATE_WAIT_FOR_DATA:
87+
if(client.available())
88+
{
89+
size_t to_read = (r.message_size - r.message_size_received) < client.available() ? r.message_size - r.message_size_received : client.available();
90+
size_t readed = client.read(&r.buffer[r.message_size_received], to_read);
91+
r.message_size_received += readed;
92+
if(r.message_size_received == r.message_size){
93+
r.state = STATE_MESSAGE_AVAILABLE;
94+
}
95+
}
96+
break;
97+
case STATE_MESSAGE_AVAILABLE:
98+
break;
99+
}
100+
}
101+
48102
size_t arduino_husarnet_transport_read(struct uxrCustomTransport *transport,
49103
uint8_t *buf, size_t len, int timeout,
50104
uint8_t *errcode) {
51105
(void)errcode;
106+
52107
client.setTimeout(timeout);
53-
return client.read(buf, len);
108+
109+
do
110+
{
111+
int64_t time_init = uxr_millis();
112+
read_tcp_data(receiver);
113+
timeout -= (int)(uxr_millis() - time_init);
114+
}
115+
while ((STATE_MESSAGE_AVAILABLE != receiver.state) && (0 < timeout));
116+
117+
if (STATE_MESSAGE_AVAILABLE == receiver.state)
118+
{
119+
size_t readed = receiver.message_size;
120+
memcpy(buf, receiver.buffer, readed);
121+
receiver.state = STATE_WAIT_FOR_SIZE;
122+
return readed;
123+
}
124+
else
125+
{
126+
return 0;
127+
}
54128
}
129+
55130
}
56131

57132
#endif

0 commit comments

Comments
 (0)