Skip to content

Commit 4e62f5e

Browse files
committed
Improve Arduino networking code
1 parent 3248075 commit 4e62f5e

File tree

3 files changed

+145
-107
lines changed

3 files changed

+145
-107
lines changed

src/tl/eth/arduino_networking.cpp

Lines changed: 76 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@
4242
#include "xcp_hw.h"
4343
/*!!! END-INCLUDE-SECTION !!!*/
4444

45-
const unsigned long READ_TIMEOUT_MS = 2000; // Timeout beim Lesen eines Frames
46-
const size_t MAX_FRAME_SIZE = 1024; // maximale erlaubte Frame-Größe
45+
const unsigned long READ_TIMEOUT_MS = 2000; // Timeout when reading a frame
4746

4847
class ClientWrapper {
4948
public:
@@ -113,11 +112,33 @@ class EthernetClientWrapper : public ClientWrapper {
113112
class EthernetUdpClientWrapper : public ClientWrapper {
114113
public:
115114

116-
EthernetUdpClientWrapper(EthernetUDP* udp, IPAddress remoteIp, uint16_t remotePort, const uint8_t* data, size_t size) :
117-
m_udp(udp), m_remoteIp(remoteIp), m_remotePort(remotePort), m_size(size), m_offset(0) {
118-
if (m_size > MAX_FRAME_SIZE)
119-
m_size = MAX_FRAME_SIZE;
120-
memcpy(m_buf, data, m_size);
115+
EthernetUdpClientWrapper() : m_udp(nullptr), m_remoteIp(), m_remotePort(0), m_size(0), m_offset(0) {
116+
}
117+
118+
void reset(EthernetUDP* udp, IPAddress remoteIp, uint16_t remotePort) {
119+
m_udp = udp;
120+
m_remoteIp = remoteIp;
121+
m_remotePort = remotePort;
122+
m_size = 0;
123+
m_offset = 0;
124+
}
125+
126+
int loadFromUdp(int packetSize) {
127+
if (!m_udp)
128+
return -1;
129+
if (packetSize <= 0)
130+
return -1;
131+
if (packetSize > (int)XCP_COMM_BUFLEN)
132+
packetSize = (int)XCP_COMM_BUFLEN;
133+
int len = m_udp->read(m_buf, (size_t)packetSize);
134+
if (len <= 0) {
135+
m_size = 0;
136+
m_offset = 0;
137+
return -1;
138+
}
139+
m_size = (size_t)len;
140+
m_offset = 0;
141+
return len;
121142
}
122143

123144
int available() override {
@@ -157,7 +178,7 @@ class EthernetUdpClientWrapper : public ClientWrapper {
157178
EthernetUDP* m_udp;
158179
IPAddress m_remoteIp;
159180
uint16_t m_remotePort;
160-
uint8_t m_buf[MAX_FRAME_SIZE];
181+
uint8_t m_buf[XCP_COMM_BUFLEN];
161182
size_t m_size;
162183
size_t m_offset;
163184
};
@@ -209,15 +230,15 @@ class EthernetAdapter : public ArduinoNetworkIf {
209230
ClientWrapper* accept_client() override {
210231
int packetSize = m_udp.parsePacket();
211232
if (packetSize > 0) {
212-
if (packetSize > (int)MAX_FRAME_SIZE)
213-
packetSize = (int)MAX_FRAME_SIZE;
214-
uint8_t buf[MAX_FRAME_SIZE];
215-
int len = m_udp.read(buf, packetSize);
216-
if (len <= 0)
217-
return nullptr;
233+
if (packetSize > (int)XCP_COMM_BUFLEN)
234+
packetSize = (int)XCP_COMM_BUFLEN;
218235
IPAddress rip = m_udp.remoteIP();
219236
uint16_t rport = m_udp.remotePort();
220-
return new EthernetUdpClientWrapper(&m_udp, rip, rport, buf, (size_t)len);
237+
m_udpClientWrapper.reset(&m_udp, rip, rport);
238+
int len = m_udpClientWrapper.loadFromUdp(packetSize);
239+
if (len <= 0)
240+
return nullptr;
241+
return &m_udpClientWrapper;
221242
}
222243
return nullptr;
223244
}
@@ -242,11 +263,33 @@ class EthernetAdapter : public ArduinoNetworkIf {
242263
class WiFiUdpClientWrapper : public ClientWrapper {
243264
public:
244265

245-
WiFiUdpClientWrapper(WiFiUDP* udp, IPAddress remoteIp, uint16_t remotePort, const uint8_t* data, size_t size) :
246-
m_udp(udp), m_remoteIp(remoteIp), m_remotePort(remotePort), m_size(size), m_offset(0) {
247-
if (m_size > MAX_FRAME_SIZE)
248-
m_size = MAX_FRAME_SIZE;
249-
memcpy(m_buf, data, m_size);
266+
WiFiUdpClientWrapper() : m_udp(nullptr), m_remoteIp(), m_remotePort(0), m_size(0), m_offset(0) {
267+
}
268+
269+
void reset(WiFiUDP* udp, IPAddress remoteIp, uint16_t remotePort) {
270+
m_udp = udp;
271+
m_remoteIp = remoteIp;
272+
m_remotePort = remotePort;
273+
m_size = 0;
274+
m_offset = 0;
275+
}
276+
277+
int loadFromUdp(int packetSize) {
278+
if (!m_udp)
279+
return -1;
280+
if (packetSize <= 0)
281+
return -1;
282+
if (packetSize > (int)XCP_COMM_BUFLEN)
283+
packetSize = (int)XCP_COMM_BUFLEN;
284+
int len = m_udp->read(m_buf, (size_t)packetSize);
285+
if (len <= 0) {
286+
m_size = 0;
287+
m_offset = 0;
288+
return -1;
289+
}
290+
m_size = (size_t)len;
291+
m_offset = 0;
292+
return len;
250293
}
251294

252295
int available() override {
@@ -286,7 +329,7 @@ class WiFiUdpClientWrapper : public ClientWrapper {
286329
WiFiUDP* m_udp;
287330
IPAddress m_remoteIp;
288331
uint16_t m_remotePort;
289-
uint8_t m_buf[MAX_FRAME_SIZE];
332+
uint8_t m_buf[XCP_COMM_BUFLEN];
290333
size_t m_size;
291334
size_t m_offset;
292335
};
@@ -314,15 +357,15 @@ class WiFiAdapter : public ArduinoNetworkIf {
314357
ClientWrapper* accept_client() override {
315358
int packetSize = m_udp.parsePacket();
316359
if (packetSize > 0) {
317-
if (packetSize > (int)MAX_FRAME_SIZE)
318-
packetSize = (int)MAX_FRAME_SIZE;
319-
uint8_t buf[MAX_FRAME_SIZE];
320-
int len = m_udp.read(buf, packetSize);
321-
if (len <= 0)
322-
return nullptr;
360+
if (packetSize > (int)XCP_COMM_BUFLEN)
361+
packetSize = (int)XCP_COMM_BUFLEN;
323362
IPAddress rip = m_udp.remoteIP();
324363
uint16_t rport = m_udp.remotePort();
325-
return new WiFiUdpClientWrapper(&m_udp, rip, rport, buf, (size_t)len);
364+
m_udpClientWrapper.reset(&m_udp, rip, rport);
365+
int len = m_udpClientWrapper.loadFromUdp(packetSize);
366+
if (len <= 0)
367+
return nullptr;
368+
return &m_udpClientWrapper;
326369
}
327370
return nullptr;
328371
}
@@ -345,10 +388,11 @@ class WiFiAdapter : public ArduinoNetworkIf {
345388

346389
private:
347390

348-
uint16_t m_port;
349-
WiFiUDP m_udp;
350-
const char* m_ssid;
351-
const char* m_pass;
391+
uint16_t m_port;
392+
WiFiUDP m_udp;
393+
const char* m_ssid;
394+
const char* m_pass;
395+
WiFiUdpClientWrapper m_udpClientWrapper; // preallocated UDP client wrapper
352396
};
353397
#endif // XCP_ON_ETHERNET_ARDUINO_DRIVER == XCP_ON_ETHERNET_DRIVER_WIFI
354398

@@ -463,7 +507,6 @@ extern "C" {
463507
void XcpTl_DeInit(void) {
464508
if (s_client) {
465509
s_client->stop();
466-
delete s_client;
467510
s_client = nullptr;
468511
}
469512
if (s_net) {
@@ -511,7 +554,6 @@ extern "C" {
511554
/* Connection lost or no data */
512555
XcpTl_ReleaseConnection();
513556
s_client->stop();
514-
delete s_client;
515557
s_client = nullptr;
516558
s_connected = false;
517559
return;
@@ -521,7 +563,6 @@ extern "C" {
521563
// XcpHw_ErrorMsg((char*)"XcpTl_RxHandler: DLC too large", EINVAL);
522564
XcpTl_ReleaseConnection();
523565
s_client->stop();
524-
delete s_client;
525566
s_client = nullptr;
526567
s_connected = false;
527568
return;
@@ -532,7 +573,6 @@ extern "C" {
532573
if (dres <= 0) {
533574
XcpTl_ReleaseConnection();
534575
s_client->stop();
535-
delete s_client;
536576
s_client = nullptr;
537577
s_connected = false;
538578
return;
@@ -545,7 +585,6 @@ extern "C" {
545585
if (!s_client->connected()) {
546586
XcpTl_ReleaseConnection();
547587
s_client->stop();
548-
delete s_client;
549588
s_client = nullptr;
550589
s_connected = false;
551590
}

tools/arduino/hello_xcp/xcp_config.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
/*
3535
** General Options.
3636
*/
37-
#define TP_CAN
38-
// #define TP_ETHER
39-
// #define TP_SXI
37+
// #define TP_CAN
38+
// #define TP_ETHER
39+
#define TP_SXI
4040

4141
#define XCP_CAN_INTERFACE (XCP_CAN_IF_SEED_STUDIO_CAN_SHIELD)
4242

tools/xcp_config.h

Lines changed: 66 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,72 @@
3838
// #define TP_ETHER
3939
#define TP_SXI
4040

41-
#define XCP_CAN_INTERFACE (XCP_CAN_IF_SEED_STUDIO_CAN_SHIELD)
41+
/*
42+
** Transport-Layer specific Options.
43+
*/
44+
#if defined(TP_CAN)
45+
#define XCP_TRANSPORT_LAYER XCP_ON_CAN
46+
#define XCP_CAN_INTERFACE (XCP_CAN_IF_SEED_STUDIO_CAN_SHIELD)
47+
48+
#define XCP_ON_CAN_INBOUND_IDENTIFIER (0x300)
49+
#define XCP_ON_CAN_OUTBOUND_IDENTIFIER (0x301)
50+
#define XCP_ON_CAN_MAX_DLC_REQUIRED (XCP_OFF)
51+
#define XCP_ON_CAN_BROADCAST_IDENTIFIER (0x222)
52+
53+
// Chip-Select- and Interrupt-Pins / SeeedStudio CAN Shield v2.
54+
#define XCP_CAN_IF_MCP25XX_PIN_CS (9)
55+
#define XCP_CAN_IF_MCP25XX_PIN_INT (2)
56+
57+
#define XCP_ON_CAN_FREQ (CAN_500KBPS)
58+
#define XCP_ON_CAN_BTQ (16)
59+
#define XCP_ON_CAN_TSEG1 (14)
60+
#define XCP_ON_CAN_TSEG2 (2)
61+
#define XCP_ON_CAN_SJW (2)
62+
#define XCP_ON_CAN_NOSAMP (1)
63+
64+
/* Transport-Layer Commands. */
65+
#define XCP_ENABLE_CAN_GET_SLAVE_ID (XCP_ON)
66+
#define XCP_ENABLE_CAN_GET_DAQ_ID (XCP_ON)
67+
#define XCP_ENABLE_CAN_SET_DAQ_ID (XCP_OFF)
68+
69+
#elif defined(TP_BLUETOOTH)
70+
#define XCP_TRANSPORT_LAYER XCP_ON_BTH
71+
72+
#define XCP_MAX_CTO (64) // (16)
73+
#define XCP_MAX_DTO (64)
74+
75+
#elif defined(TP_ETHER)
76+
#define XCP_TRANSPORT_LAYER XCP_ON_ETHERNET
77+
78+
#define XCP_ON_ETHERNET_IP (192, 168, 0, 100)
79+
#define XCP_ON_ETHERNET_PORT (5555)
80+
81+
#define XCP_ON_ETHERNET_ARDUINO_DRIVER (XCP_ON_ETHERNET_DRIVER_ETHERNET)
82+
#define XCP_ON_ETHERNET_WIFI_SSID ("")
83+
#define XCP_ON_ETHERNET_WIFI_PASSWORD ("")
84+
#define XCP_ON_ETHERNET_MAC_ADDRESS { 0xBE, 0xEF, 0xCA, 0xAA, 0xFF, 0xFE }
85+
86+
#define XCP_MAX_CTO (64) // (16)
87+
#define XCP_MAX_DTO (64)
88+
89+
#elif defined(TP_SXI) || (XCP_TRANSPORT_LAYER == XCP_ON_SXI)
90+
/* Allow command-line or parent CMake to override these via -D defines */
91+
#define XCP_TRANSPORT_LAYER XCP_ON_SXI
92+
#define XCP_ON_SXI_HEADER_FORMAT (XCP_ON_SXI_HEADER_LEN_CTR_WORD)
93+
#define XCP_ON_SXI_BITRATE (38400)
94+
#define XCP_ON_SXI_CONFIG (SERIAL_8N1)
95+
#define XCP_MAX_CTO (64)
96+
#define XCP_MAX_DTO (64)
97+
#define XCP_ON_SXI_TAIL_CHECKSUM (XCP_ON_SXI_NO_CHECKSUM)
98+
/* Framing and escaping (as used by xcp_tl.c) */
99+
#define XCP_ON_SXI_ENABLE_FRAMING (XCP_OFF)
100+
#define XCP_ON_SXI_SYNC_CHAR (0xAA)
101+
#define XCP_ON_SXI_ESC_CHAR (0xAB)
102+
#define XCP_ON_SXI_ESC_SYNC_CHAR (0x01)
103+
#define XCP_ON_SXI_ESC_ESC_CHAR (0x00)
104+
#else
105+
#error "No transport-layer. please define either TP_ETHER, TP_CAN, or TP_BLUETOOTH."
106+
#endif // KVASER_CAN
42107

43108
#define XCP_GET_ID_0 "BlueParrot XCP running on Arduino"
44109
#define XCP_GET_ID_1 "BlueParrot_XCP_on_Arduino"
@@ -165,72 +230,6 @@
165230
#define XCP_ENABLE_EVENT_PACKET_API (XCP_ON)
166231
#define XCP_ENABLE_SERVICE_REQUEST_API (XCP_OFF)
167232

168-
/*
169-
** Transport-Layer specific Options (may not apply to every Transport).
170-
*/
171-
#if defined(TP_CAN)
172-
#define XCP_TRANSPORT_LAYER XCP_ON_CAN
173-
174-
#define XCP_ON_CAN_INBOUND_IDENTIFIER (0x300)
175-
#define XCP_ON_CAN_OUTBOUND_IDENTIFIER (0x301)
176-
#define XCP_ON_CAN_MAX_DLC_REQUIRED (XCP_OFF)
177-
#define XCP_ON_CAN_BROADCAST_IDENTIFIER (0x222)
178-
179-
// Chip-Select- and Interrupt-Pins / SeeedStudio CAN Shield v2.
180-
#define XCP_CAN_IF_MCP25XX_PIN_CS (9)
181-
#define XCP_CAN_IF_MCP25XX_PIN_INT (2)
182-
183-
#define XCP_ON_CAN_FREQ (CAN_500KBPS)
184-
#define XCP_ON_CAN_BTQ (16)
185-
#define XCP_ON_CAN_TSEG1 (14)
186-
#define XCP_ON_CAN_TSEG2 (2)
187-
#define XCP_ON_CAN_SJW (2)
188-
#define XCP_ON_CAN_NOSAMP (1)
189-
190-
/* Transport-Layer Commands. */
191-
#define XCP_ENABLE_CAN_GET_SLAVE_ID (XCP_ON)
192-
#define XCP_ENABLE_CAN_GET_DAQ_ID (XCP_ON)
193-
#define XCP_ENABLE_CAN_SET_DAQ_ID (XCP_OFF)
194-
195-
#elif defined(TP_BLUETOOTH)
196-
#define XCP_TRANSPORT_LAYER XCP_ON_BTH
197-
198-
#define XCP_MAX_CTO (64) // (16)
199-
#define XCP_MAX_DTO (64)
200-
201-
#elif defined(TP_ETHER)
202-
#define XCP_TRANSPORT_LAYER XCP_ON_ETHERNET
203-
204-
#define XCP_ON_ETHERNET_IP (192, 168, 0, 100)
205-
#define XCP_ON_ETHERNET_PORT (5555)
206-
207-
#define XCP_ON_ETHERNET_ARDUINO_DRIVER (XCP_ON_ETHERNET_DRIVER_ETHERNET)
208-
#define XCP_ON_ETHERNET_WIFI_SSID ("")
209-
#define XCP_ON_ETHERNET_WIFI_PASSWORD ("")
210-
#define XCP_ON_ETHERNET_MAC_ADDRESS { 0xBE, 0xEF, 0xCA, 0xAA, 0xFF, 0xFE }
211-
212-
#define XCP_MAX_CTO (64) // (16)
213-
#define XCP_MAX_DTO (64)
214-
215-
#elif defined(TP_SXI) || (XCP_TRANSPORT_LAYER == XCP_ON_SXI)
216-
/* Allow command-line or parent CMake to override these via -D defines */
217-
#define XCP_TRANSPORT_LAYER XCP_ON_SXI
218-
#define XCP_ON_SXI_HEADER_FORMAT (XCP_ON_SXI_HEADER_LEN_CTR_WORD)
219-
#define XCP_ON_SXI_BITRATE (38400)
220-
#define XCP_ON_SXI_CONFIG (SERIAL_8N1)
221-
#define XCP_MAX_CTO (64)
222-
#define XCP_MAX_DTO (64)
223-
#define XCP_ON_SXI_TAIL_CHECKSUM (XCP_ON_SXI_NO_CHECKSUM)
224-
/* Framing and escaping (as used by xcp_tl.c) */
225-
#define XCP_ON_SXI_ENABLE_FRAMING (XCP_OFF)
226-
#define XCP_ON_SXI_SYNC_CHAR (0xAA)
227-
#define XCP_ON_SXI_ESC_CHAR (0xAB)
228-
#define XCP_ON_SXI_ESC_SYNC_CHAR (0x01)
229-
#define XCP_ON_SXI_ESC_ESC_CHAR (0x00)
230-
#else
231-
#error "No transport-layer. please define either TP_ETHER, TP_CAN, or TP_BLUETOOTH."
232-
#endif // KVASER_CAN
233-
234233
/*
235234
** Customization Options.
236235
*/

0 commit comments

Comments
 (0)