Skip to content

Commit 9e05471

Browse files
added tcp write example for tcp echo server
1 parent aa3c5a1 commit 9e05471

File tree

1 file changed

+301
-0
lines changed

1 file changed

+301
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
#include <Arduino.h>
2+
#include <Arduino_DebugUtils.h>
3+
#include <IRQManager.h>
4+
#include <regex>
5+
#include <utils.h>
6+
7+
// #define CNETIF_STATS_ENABLED
8+
// #include "CNetifStats.h"
9+
10+
#ifdef CNETIF_STATS_ENABLED
11+
#define STATS_BUFFER_SIZE 1000
12+
char cnetif_stats_buffer[STATS_BUFFER_SIZE];
13+
// netif_stats _stats;
14+
#endif // CNETIF_STATS_ENABLED
15+
16+
#include <EthernetC33.h>
17+
#include <lwipClient.h>
18+
19+
#define CHECK_PAYLOAD
20+
21+
/* --------------------------------------- */
22+
void timer_cb(timer_callback_args_t *arg);
23+
void application();
24+
void dump_buffer(uint8_t* b, uint32_t len, uint8_t blocks=4, uint8_t cols=16);
25+
void dump_buffer_char(uint8_t* b, uint32_t len);
26+
uint64_t debug_start;
27+
/* --------------------------------------- */
28+
29+
void setup() {
30+
Serial.begin(115200);
31+
while(!Serial);
32+
33+
Serial.println("Renesas file download example");
34+
35+
IPAddress ip(192, 168, 10, 130);
36+
IPAddress gw(192, 168, 10, 1);
37+
IPAddress nm(255, 255, 255, 0);
38+
39+
DEBUG_INFO("Setting up netif");
40+
Ethernet.begin(ip, nm, gw);
41+
// Ethernet.begin();
42+
43+
DEBUG_INFO("Begin of reception\n\n");
44+
debug_start = millis();
45+
}
46+
47+
uint32_t counter=0;
48+
void loop() {
49+
// __disable_irq();
50+
uint32_t start = micros();
51+
#ifndef LWIP_USE_TIMER
52+
CLwipIf::getInstance().task();
53+
#endif
54+
// Handle application FSM
55+
application();
56+
57+
if(millis() - debug_start > 3000) { // print the debug _stats every x second
58+
// DEBUG_INFO("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
59+
DEBUG_INFO("time: %12ums", millis());
60+
// DEBUG_INFO("memory: %12u bytes \tmin: %12u bytes \tmax: %12u bytes",
61+
// memory_used, memory_used_min, memory_used_max);
62+
DEBUG_INFO("loop counter %u\n", counter);
63+
// application_report();
64+
65+
#ifdef CNETIF_STATS_ENABLED
66+
netif_stats_sprintf(cnetif_stats_buffer, Ethernet.stats, STATS_BUFFER_SIZE, (8*1e6)/(1<<20), "Mbit/s");
67+
// __disable_irq();
68+
arduino::lock();
69+
NETIF_STATS_RESET_AVERAGES(Ethernet.stats);
70+
// __enable_irq();
71+
arduino::unlock();
72+
73+
DEBUG_INFO(cnetif_stats_buffer);
74+
#endif // CNETIF_STATS_ENABLED
75+
// DEBUG_INFO("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
76+
77+
counter = 0;
78+
// reset some counters
79+
debug_start = millis();
80+
}
81+
counter++;
82+
}
83+
84+
// Application level Stuff
85+
enum app_state_t: uint8_t {
86+
APP_STATE_NONE = 0,
87+
APP_STATE_LINK_UP,
88+
APP_STATE_LINK_DOWN,
89+
APP_STATE_IFACE_UP,
90+
APP_STATE_CONNECTING,
91+
APP_STATE_CONNECTED,
92+
APP_STATE_SEND,
93+
APP_STATE_RECEIVE,
94+
APP_STATE_ERROR,
95+
APP_STATE_RESET
96+
};
97+
98+
static const char* state_strings[] = {
99+
"APP_STATE_NONE",
100+
"APP_STATE_LINK_UP",
101+
"APP_STATE_LINK_DOWN",
102+
"APP_STATE_IFACE_UP",
103+
"APP_STATE_CONNECTING",
104+
"APP_STATE_CONNECTED",
105+
"APP_STATE_SEND",
106+
"APP_STATE_RECEIVE",
107+
"APP_STATE_ERROR",
108+
"APP_STATE_RESET"
109+
};
110+
111+
#define APP_BUFFER_SIZE 1*1024
112+
113+
typedef uint32_t counter_t;
114+
115+
struct App {
116+
app_state_t current_state=APP_STATE_NONE;
117+
app_state_t prev_state=APP_STATE_NONE;
118+
119+
lwipClient *tcp_client;
120+
uint16_t port = 2000;
121+
IPAddress server_ip = IPAddress(192, 168, 10, 250);
122+
123+
counter_t counter;
124+
uint8_t buffer[APP_BUFFER_SIZE];
125+
126+
size_t file_length=0;
127+
size_t downloaded_bytes=0;
128+
std::string http_header;
129+
130+
// stats related variables
131+
uint32_t start = 0;
132+
uint32_t speed_start = 0;
133+
uint32_t speed_bytes = 0;
134+
135+
// payload verification parameters
136+
uint32_t payload_verify_offset=0;
137+
uint8_t payload_verify_excess[4]={}; // this should be 3, but there are bugs
138+
uint8_t payload_verify_excess_len=0;
139+
uint32_t last_value=0;
140+
} app;
141+
142+
void init_app(struct App& app) {
143+
app.file_length = 0;
144+
app.http_header = "";
145+
app.downloaded_bytes = 0;
146+
app.start = 0;
147+
app.payload_verify_excess_len = 0;
148+
app.payload_verify_offset = 0;
149+
app.last_value=0;
150+
app.speed_bytes = 0;
151+
app.counter = 0;
152+
}
153+
154+
void reset_app(struct App& app) {
155+
init_app(app);
156+
157+
if(app.tcp_client != nullptr) {
158+
app.tcp_client->stop();
159+
// delete app.tcp_client;
160+
}
161+
}
162+
163+
void application() {
164+
bool found = false;
165+
uint16_t bytes_read=0;
166+
167+
switch(app.current_state) {
168+
case APP_STATE_NONE:
169+
init_app(app);
170+
171+
// TODO we are not handling link connection and disconnection
172+
app.prev_state = app.current_state;
173+
app.current_state = APP_STATE_LINK_UP;
174+
DEBUG_INFO("State changed: to %s, from %s",
175+
state_strings[app.current_state],
176+
state_strings[app.prev_state]);
177+
break;
178+
179+
case APP_STATE_LINK_UP:
180+
if(Ethernet.isDhcpAcquired()) {
181+
app.prev_state = app.current_state;
182+
app.current_state = APP_STATE_IFACE_UP;
183+
DEBUG_INFO("State changed: to %s, from %s",
184+
state_strings[app.current_state],
185+
state_strings[app.prev_state]);
186+
}
187+
break;
188+
case APP_STATE_IFACE_UP:
189+
// The link is up we connect to the server
190+
app.tcp_client = new lwipClient;
191+
192+
// Connection details:
193+
app.tcp_client->connect(app.server_ip, app.port);
194+
195+
app.prev_state = app.current_state;
196+
app.current_state = APP_STATE_CONNECTING;
197+
DEBUG_INFO("State changed: to %s, from %s",
198+
state_strings[app.current_state],
199+
state_strings[app.prev_state]);
200+
break;
201+
202+
case APP_STATE_CONNECTING:
203+
// do nothing, until the TCP connection is established
204+
// TODO handle timeout for connection and go to error state
205+
if(app.tcp_client->connected()) {
206+
app.prev_state = app.current_state;
207+
app.current_state = APP_STATE_SEND;
208+
DEBUG_INFO("State changed: to %s, from %s",
209+
state_strings[app.current_state],
210+
state_strings[app.prev_state]);
211+
}
212+
213+
break;
214+
215+
case APP_STATE_CONNECTED:
216+
app.start = millis();
217+
app.speed_start = app.start;
218+
219+
app.prev_state = app.current_state;
220+
app.current_state = APP_STATE_SEND;
221+
DEBUG_INFO("State changed: to %s, from %s",
222+
state_strings[app.current_state],
223+
state_strings[app.prev_state]);
224+
break;
225+
case APP_STATE_SEND: {
226+
int res = app.tcp_client->write((uint8_t*)&app.counter, sizeof(counter_t));
227+
DEBUG_INFO("counter sent, value 0x%08X, res: %d", app.counter, res);
228+
229+
if(res == sizeof(counter_t)) {
230+
app.counter++;
231+
app.prev_state = app.current_state;
232+
app.current_state = APP_STATE_RECEIVE;
233+
// DEBUG_INFO("State changed: to %s, from %s",
234+
// state_strings[app.current_state],
235+
// state_strings[app.prev_state]);
236+
}
237+
break;
238+
}
239+
case APP_STATE_RECEIVE: {
240+
counter_t read_counter;
241+
bytes_read = app.tcp_client->read((uint8_t*)&read_counter, sizeof(counter_t));
242+
243+
if(bytes_read == sizeof(counter_t)) {
244+
DEBUG_INFO("counter echoed, value 0x%08X", read_counter);
245+
246+
app.prev_state = app.current_state;
247+
app.current_state = APP_STATE_SEND;
248+
// DEBUG_INFO("State changed: to %s, from %s",
249+
// state_strings[app.current_state],
250+
// state_strings[app.prev_state]);
251+
}
252+
break;
253+
}
254+
case APP_STATE_ERROR:
255+
// The app reached an expected error state
256+
// TODO report this state and go in the default, status not defined handler to reset the state
257+
case APP_STATE_RESET:
258+
// in this state we reset the application and we start back from the beginning
259+
260+
reset_app(app);
261+
262+
app.prev_state = app.current_state;
263+
app.current_state = APP_STATE_IFACE_UP;
264+
DEBUG_INFO("State changed: to %s, from %s",
265+
state_strings[app.current_state],
266+
state_strings[app.prev_state]);
267+
break;
268+
}
269+
}
270+
271+
// Utility functions
272+
void dump_buffer(uint8_t* b, uint32_t len, uint8_t blocks, uint8_t cols) {
273+
274+
// TODO make sure blocks is less that cols
275+
Serial.println("BUFFER >>>>>>>");
276+
for(uint8_t *p=b; p<b+len; p++) {
277+
if(p == nullptr) {
278+
break;
279+
}
280+
if(*p < 0x10) {
281+
Serial.print(0);
282+
}
283+
Serial.print(*p, HEX);
284+
285+
if(cols != 0 && ((p-b)+1) % blocks == 0 && ((p-b)+1) % cols != 0){
286+
Serial.print(" ");
287+
}
288+
if(cols != 0 && ((p-b)+1) % cols == 0){
289+
Serial.println();
290+
}
291+
}
292+
Serial.println("\nBUFFER <<<<<<<");
293+
}
294+
295+
void dump_buffer_char(uint8_t* b, uint32_t len) {
296+
Serial.println("BUFFER_CHAR >>>>>>>");
297+
for(uint8_t *p=b; p<b+len; p++) {
298+
Serial.print((char)*p);
299+
}
300+
Serial.println("\nBUFFER_CHAR <<<<<<<");
301+
}

0 commit comments

Comments
 (0)