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 (" \n BUFFER <<<<<<<" );
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 (" \n BUFFER_CHAR <<<<<<<" );
301
+ }
0 commit comments