@@ -35,23 +35,98 @@ size_t arduino_husarnet_transport_write(struct uxrCustomTransport *transport,
35
35
const uint8_t *buf, size_t len,
36
36
uint8_t *errcode) {
37
37
(void )errcode;
38
- struct micro_ros_agent_locator *locator =
39
- (struct micro_ros_agent_locator *)transport->args ;
40
38
41
- Serial1.printf (" transport_write:\r\n\t buf:%s\r\n\t len:%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 );
42
44
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
+ }
44
51
45
52
return sent;
46
53
}
47
54
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
+
48
102
size_t arduino_husarnet_transport_read (struct uxrCustomTransport *transport,
49
103
uint8_t *buf, size_t len, int timeout,
50
104
uint8_t *errcode) {
51
105
(void )errcode;
106
+
52
107
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
+ }
54
128
}
129
+
55
130
}
56
131
57
132
#endif
0 commit comments