Skip to content
This repository was archived by the owner on Jan 29, 2023. It is now read-only.

Commit 8f38ab4

Browse files
authored
v1.0.1 to add Ethernet2 and Ethernet3 support
### New in v1.0.1 1. Add support to **W5x00 using Ethernet2 or Ethernet3 library** 2. Update Platform.ini to support PlatformIO 5.x owner-based dependency declaration. 3. Update Packages' Patches. 4. Update Libraries' Patches for Ethernet2 library to add Multicast feature necessary for this [MDNS_Generic library](https://github.com/khoih-prog/MDNS_Generic) 5. Enhance examples.
1 parent a4a3c94 commit 8f38ab4

File tree

31 files changed

+3119
-156
lines changed

31 files changed

+3119
-156
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
/*
2+
* Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
3+
* This version only offers minimal wrapping of socket.c/socket.h
4+
* Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
5+
*
6+
* MIT License:
7+
* Copyright (c) 2008 Bjoern Hartmann
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*
26+
* bjoern@cs.stanford.edu 12/30/2008
27+
*
28+
* - 10 Apr. 2015
29+
* Added support for Arduino Ethernet Shield 2
30+
* by Arduino.org team
31+
*/
32+
33+
#include "utility/w5500.h"
34+
#include "utility/socket.h"
35+
#include "Ethernet2.h"
36+
#include "Udp.h"
37+
#include "Dns.h"
38+
39+
#define ETHERNET2_DEBUG 0
40+
41+
/* Constructor */
42+
EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {}
43+
44+
/* Start EthernetUDP socket, listening at local port PORT */
45+
uint8_t EthernetUDP::begin(uint16_t port) {
46+
if (_sock != MAX_SOCK_NUM)
47+
return 0;
48+
49+
for (int i = 0; i < MAX_SOCK_NUM; i++) {
50+
uint8_t s = w5500.readSnSR(i);
51+
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
52+
_sock = i;
53+
break;
54+
}
55+
}
56+
57+
if (_sock == MAX_SOCK_NUM)
58+
return 0;
59+
60+
_port = port;
61+
_remaining = 0;
62+
socket(_sock, SnMR::UDP, _port, 0);
63+
64+
return 1;
65+
}
66+
67+
//KH, to add Multicast support
68+
/* Start EthernetUDP socket, listening at local port PORT */
69+
uint8_t EthernetUDP::beginMulticast(IPAddress ip, uint16_t port)
70+
{
71+
if (_sock != MAX_SOCK_NUM)
72+
return 0;
73+
74+
for (int i = 0; i < MAX_SOCK_NUM; i++) {
75+
uint8_t s = w5500.readSnSR(i);
76+
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
77+
_sock = i;
78+
break;
79+
}
80+
}
81+
82+
if (_sock == MAX_SOCK_NUM)
83+
return 0;
84+
85+
// Calculate MAC address from Multicast IP Address
86+
byte mac[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 };
87+
88+
mac[3] = ip[1] & 0x7F;
89+
mac[4] = ip[2];
90+
mac[5] = ip[3];
91+
92+
w5500.writeSnDIPR(_sock, rawIPAddress(ip)); //239.255.0.1
93+
w5500.writeSnDPORT(_sock, port);
94+
w5500.writeSnDHAR(_sock,mac);
95+
96+
_remaining = 0;
97+
socket(_sock, SnMR::UDP, port, SnMR::MULTI);
98+
return 1;
99+
}
100+
//////
101+
102+
103+
104+
/* return number of bytes available in the current packet,
105+
will return zero if parsePacket hasn't been called yet */
106+
int EthernetUDP::available() {
107+
return _remaining;
108+
}
109+
110+
/* Release any resources being used by this EthernetUDP instance */
111+
void EthernetUDP::stop()
112+
{
113+
if (_sock == MAX_SOCK_NUM)
114+
return;
115+
116+
close(_sock);
117+
118+
EthernetClass::_server_port[_sock] = 0;
119+
_sock = MAX_SOCK_NUM;
120+
}
121+
122+
int EthernetUDP::beginPacket(const char *host, uint16_t port)
123+
{
124+
// Look up the host first
125+
int ret = 0;
126+
DNSClient dns;
127+
IPAddress remote_addr;
128+
129+
dns.begin(Ethernet.dnsServerIP());
130+
ret = dns.getHostByName(host, remote_addr);
131+
if (ret == 1) {
132+
return beginPacket(remote_addr, port);
133+
} else {
134+
return ret;
135+
}
136+
}
137+
138+
int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
139+
{
140+
_offset = 0;
141+
142+
// KH debug
143+
#if (ETHERNET2_DEBUG > 1)
144+
Serial.print("Ethernet2UDP::beginPacket: ip=");
145+
Serial.print(ip);
146+
Serial.print(", port=");
147+
Serial.println(port);
148+
#endif
149+
150+
return startUDP(_sock, rawIPAddress(ip), port);
151+
}
152+
153+
int EthernetUDP::endPacket()
154+
{
155+
return sendUDP(_sock);
156+
}
157+
158+
size_t EthernetUDP::write(uint8_t byte)
159+
{
160+
return write(&byte, 1);
161+
}
162+
163+
size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
164+
{
165+
// KH debug
166+
#if (ETHERNET2_DEBUG > 1)
167+
Serial.print("Ethernet2UDP:write, size=");
168+
Serial.println(size);
169+
#endif
170+
171+
uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
172+
_offset += bytes_written;
173+
174+
// KH debug
175+
#if (ETHERNET2_DEBUG > 1)
176+
Serial.print("Ethernet2UDP: bytes written=");
177+
Serial.println(bytes_written);
178+
#endif
179+
180+
return bytes_written;
181+
}
182+
183+
int EthernetUDP::parsePacket()
184+
{
185+
// discard any remaining bytes in the last packet
186+
flush();
187+
188+
if (w5500.getRXReceivedSize(_sock) > 0)
189+
{
190+
//HACK - hand-parse the UDP packet using TCP recv method
191+
uint8_t tmpBuf[8];
192+
int ret =0;
193+
//read 8 header bytes and get IP and port from it
194+
ret = recv(_sock,tmpBuf,8);
195+
if (ret > 0)
196+
{
197+
_remoteIP = tmpBuf;
198+
_remotePort = tmpBuf[4];
199+
_remotePort = (_remotePort << 8) + tmpBuf[5];
200+
_remaining = tmpBuf[6];
201+
_remaining = (_remaining << 8) + tmpBuf[7];
202+
203+
// When we get here, any remaining bytes are the data
204+
ret = _remaining;
205+
}
206+
207+
// KH debug
208+
#if (ETHERNET2_DEBUG > 1)
209+
Serial.print("Ethernet2UDP:parsePacket OK, datasize=");
210+
Serial.println(ret);
211+
#endif
212+
213+
return ret;
214+
}
215+
// There aren't any packets available
216+
return 0;
217+
}
218+
219+
int EthernetUDP::read()
220+
{
221+
uint8_t byte;
222+
223+
if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
224+
{
225+
// We read things without any problems
226+
_remaining--;
227+
return byte;
228+
}
229+
230+
// If we get here, there's no data available
231+
return -1;
232+
}
233+
234+
int EthernetUDP::read(unsigned char* buffer, size_t len)
235+
{
236+
237+
if (_remaining > 0)
238+
{
239+
240+
int got;
241+
242+
if (_remaining <= len)
243+
{
244+
// data should fit in the buffer
245+
got = recv(_sock, buffer, _remaining);
246+
}
247+
else
248+
{
249+
// too much data for the buffer,
250+
// grab as much as will fit
251+
got = recv(_sock, buffer, len);
252+
}
253+
254+
if (got > 0)
255+
{
256+
_remaining -= got;
257+
return got;
258+
}
259+
260+
}
261+
262+
// If we get here, there's no data available or recv failed
263+
return -1;
264+
265+
}
266+
267+
int EthernetUDP::peek()
268+
{
269+
uint8_t b;
270+
// Unlike recv, peek doesn't check to see if there's any data available, so we must.
271+
// If the user hasn't called parsePacket yet then return nothing otherwise they
272+
// may get the UDP header
273+
if (!_remaining)
274+
return -1;
275+
::peek(_sock, &b);
276+
return b;
277+
}
278+
279+
void EthernetUDP::flush()
280+
{
281+
// could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
282+
// should only occur if recv fails after telling us the data is there, lets
283+
// hope the w5500 always behaves :)
284+
285+
while (_remaining)
286+
{
287+
read();
288+
}
289+
}
290+

0 commit comments

Comments
 (0)