Skip to content

Commit a6093a8

Browse files
committed
Created an abstract base class UDP to match the Client and Server classes, and reworked the Ethernet library to use it and derive EthernetUDP.
1 parent ad5dead commit a6093a8

File tree

8 files changed

+131
-42
lines changed

8 files changed

+131
-42
lines changed

hardware/arduino/cores/arduino/Udp.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Udp.cpp: Library to send/receive UDP packets.
3+
*
4+
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
5+
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
6+
* might not happen often in practice, but in larger network topologies, a UDP
7+
* packet can be received out of sequence.
8+
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
9+
* aware of it. Again, this may not be a concern in practice on small local networks.
10+
* For more information, see http://www.cafeaulait.org/course/week12/35.html
11+
*
12+
* MIT License:
13+
* Copyright (c) 2008 Bjoern Hartmann
14+
* Permission is hereby granted, free of charge, to any person obtaining a copy
15+
* of this software and associated documentation files (the "Software"), to deal
16+
* in the Software without restriction, including without limitation the rights
17+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18+
* copies of the Software, and to permit persons to whom the Software is
19+
* furnished to do so, subject to the following conditions:
20+
*
21+
* The above copyright notice and this permission notice shall be included in
22+
* all copies or substantial portions of the Software.
23+
*
24+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30+
* THE SOFTWARE.
31+
*
32+
* bjoern@cs.stanford.edu 12/30/2008
33+
*/
34+
35+
#ifndef udp_h
36+
#define udp_h
37+
38+
#include <Stream.h>
39+
#include <IPAddress.h>
40+
41+
class UDP : public Stream {
42+
43+
public:
44+
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
45+
virtual void stop() =0; // Finish with the UDP socket
46+
47+
// Sending UDP packets
48+
49+
// Start building up a packet to send to the remote host specific in ip and port
50+
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
51+
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
52+
// Start building up a packet to send to the remote host specific in host and port
53+
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
54+
virtual int beginPacket(const char *host, uint16_t port) =0;
55+
// Finish off this packet and send it
56+
// Returns 1 if the packet was sent successfully, 0 if there was an error
57+
virtual int endPacket() =0;
58+
// Write a single byte into the packet
59+
virtual size_t write(uint8_t) =0;
60+
// Write a string of characters into the packet
61+
virtual size_t write(const char *str) =0;
62+
// Write size bytes from buffer into the packet
63+
virtual size_t write(const uint8_t *buffer, size_t size) =0;
64+
65+
// Start processing the next available incoming packet
66+
// Returns the size of the packet in bytes, or 0 if no packets are available
67+
virtual int parsePacket() =0;
68+
// Number of bytes remaining in the current packet
69+
virtual int available() =0;
70+
// Read a single byte from the current packet
71+
virtual int read() =0;
72+
// Read up to len bytes from the current packet and place them into buffer
73+
// Returns the number of bytes read, or 0 if none are available
74+
virtual int read(unsigned char* buffer, size_t len) =0;
75+
// Read up to len characters from the current packet and place them into buffer
76+
// Returns the number of characters read, or 0 if none are available
77+
virtual int read(char* buffer, size_t len) =0;
78+
// Return the next byte from the current packet without moving on to the next byte
79+
virtual int peek() =0;
80+
virtual void flush() =0; // Finish reading the current packet
81+
82+
// Return the IP address of the host who sent the current incoming packet
83+
virtual IPAddress remoteIP() =0;
84+
// Return the port of the host who sent the current incoming packet
85+
virtual uint16_t remotePort() =0;
86+
protected:
87+
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
88+
};
89+
90+
#endif

libraries/Ethernet/Dhcp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#ifndef Dhcp_h
55
#define Dhcp_h
66

7-
#include "Udp.h"
7+
#include "EthernetUdp.h"
88

99
/* DHCP state machine. */
1010
#define STATE_DHCP_START 0
@@ -139,7 +139,7 @@ class DhcpClass {
139139
uint8_t _dhcpGatewayIp[4];
140140
uint8_t _dhcpDhcpServerIp[4];
141141
uint8_t _dhcpDnsServerIp[4];
142-
UDP _dhcpUdpSocket;
142+
EthernetUDP _dhcpUdpSocket;
143143

144144
void presend_DHCP();
145145
void send_DHCP_MESSAGE(uint8_t, uint16_t);

libraries/Ethernet/Dns.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Released under Apache License, version 2.0
44

55
#include "w5100.h"
6-
#include "Udp.h"
6+
#include "EthernetUdp.h"
77
#include "util.h"
88

99
#include "Dns.h"

libraries/Ethernet/Dns.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#ifndef DNSClient_h
66
#define DNSClient_h
77

8-
#include <Udp.h>
8+
#include <EthernetUdp.h>
99

1010
class DNSClient
1111
{
@@ -35,7 +35,7 @@ class DNSClient
3535

3636
IPAddress iDNSServer;
3737
uint16_t iRequestId;
38-
UDP iUdp;
38+
EthernetUDP iUdp;
3939
};
4040

4141
#endif

libraries/Ethernet/Udp.cpp renamed to libraries/Ethernet/EthernetUdp.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@
3333
#include "Dns.h"
3434

3535
/* Constructor */
36-
UDP::UDP() : _sock(MAX_SOCK_NUM) {}
36+
EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {}
3737

38-
/* Start UDP socket, listening at local port PORT */
39-
uint8_t UDP::begin(uint16_t port) {
38+
/* Start EthernetUDP socket, listening at local port PORT */
39+
uint8_t EthernetUDP::begin(uint16_t port) {
4040
if (_sock != MAX_SOCK_NUM)
4141
return 0;
4242

@@ -59,12 +59,12 @@ uint8_t UDP::begin(uint16_t port) {
5959

6060
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
6161
* returned value includes 8 byte UDP header!*/
62-
int UDP::available() {
62+
int EthernetUDP::available() {
6363
return W5100.getRXReceivedSize(_sock);
6464
}
6565

66-
/* Release any resources being used by this UDP instance */
67-
void UDP::stop()
66+
/* Release any resources being used by this EthernetUDP instance */
67+
void EthernetUDP::stop()
6868
{
6969
if (_sock == MAX_SOCK_NUM)
7070
return;
@@ -75,7 +75,7 @@ void UDP::stop()
7575
_sock = MAX_SOCK_NUM;
7676
}
7777

78-
int UDP::beginPacket(const char *host, uint16_t port)
78+
int EthernetUDP::beginPacket(const char *host, uint16_t port)
7979
{
8080
// Look up the host first
8181
int ret = 0;
@@ -91,36 +91,36 @@ int UDP::beginPacket(const char *host, uint16_t port)
9191
}
9292
}
9393

94-
int UDP::beginPacket(IPAddress ip, uint16_t port)
94+
int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
9595
{
9696
_offset = 0;
97-
return startUDP(_sock, ip.raw_address(), port);
97+
return startUDP(_sock, rawIPAddress(ip), port);
9898
}
9999

100-
int UDP::endPacket()
100+
int EthernetUDP::endPacket()
101101
{
102102
return sendUDP(_sock);
103103
}
104104

105-
size_t UDP::write(uint8_t byte)
105+
size_t EthernetUDP::write(uint8_t byte)
106106
{
107107
return write(&byte, 1);
108108
}
109109

110-
size_t UDP::write(const char *str)
110+
size_t EthernetUDP::write(const char *str)
111111
{
112112
size_t len = strlen(str);
113113
return write((const uint8_t *)str, len);
114114
}
115115

116-
size_t UDP::write(const uint8_t *buffer, size_t size)
116+
size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
117117
{
118118
uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
119119
_offset += bytes_written;
120120
return bytes_written;
121121
}
122122

123-
int UDP::parsePacket()
123+
int EthernetUDP::parsePacket()
124124
{
125125
if (available() > 0)
126126
{
@@ -143,7 +143,7 @@ int UDP::parsePacket()
143143
return 0;
144144
}
145145

146-
int UDP::read()
146+
int EthernetUDP::read()
147147
{
148148
uint8_t byte;
149149
if (recv(_sock, &byte, 1) > 0)
@@ -155,7 +155,7 @@ int UDP::read()
155155
return -1;
156156
}
157157

158-
int UDP::read(unsigned char* buffer, size_t len)
158+
int EthernetUDP::read(unsigned char* buffer, size_t len)
159159
{
160160
/* In the readPacket that copes with truncating packets, the buffer was
161161
filled with this code. Not sure why it loops round reading out a byte
@@ -169,7 +169,7 @@ int UDP::read(unsigned char* buffer, size_t len)
169169
return recv(_sock, buffer, len);
170170
}
171171

172-
int UDP::peek()
172+
int EthernetUDP::peek()
173173
{
174174
uint8_t b;
175175
// Unlike recv, peek doesn't check to see if there's any data available, so we must
@@ -179,7 +179,7 @@ int UDP::peek()
179179
return b;
180180
}
181181

182-
void UDP::flush()
182+
void EthernetUDP::flush()
183183
{
184184
while (available())
185185
{

libraries/Ethernet/Udp.h renamed to libraries/Ethernet/EthernetUdp.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,14 @@
3434
* bjoern@cs.stanford.edu 12/30/2008
3535
*/
3636

37-
#ifndef udp_h
38-
#define udp_h
37+
#ifndef ethernetudp_h
38+
#define ethernetudp_h
3939

40-
#include <Stream.h>
41-
#include <IPAddress.h>
40+
#include <Udp.h>
4241

4342
#define UDP_TX_PACKET_MAX_SIZE 24
4443

45-
class UDP : public Stream {
44+
class EthernetUDP : public UDP {
4645
private:
4746
uint8_t _sock; // socket ID for Wiz5100
4847
uint16_t _port; // local port to listen on
@@ -51,21 +50,21 @@ class UDP : public Stream {
5150
uint16_t _offset; // offset into the packet being sent
5251

5352
public:
54-
UDP(); // Constructor
55-
uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
56-
void stop(); // Finish with the UDP socket
53+
EthernetUDP(); // Constructor
54+
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
55+
virtual void stop(); // Finish with the UDP socket
5756

5857
// Sending UDP packets
5958

6059
// Start building up a packet to send to the remote host specific in ip and port
6160
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
62-
int beginPacket(IPAddress ip, uint16_t port);
61+
virtual int beginPacket(IPAddress ip, uint16_t port);
6362
// Start building up a packet to send to the remote host specific in host and port
6463
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
65-
int beginPacket(const char *host, uint16_t port);
64+
virtual int beginPacket(const char *host, uint16_t port);
6665
// Finish off this packet and send it
6766
// Returns 1 if the packet was sent successfully, 0 if there was an error
68-
int endPacket();
67+
virtual int endPacket();
6968
// Write a single byte into the packet
7069
virtual size_t write(uint8_t);
7170
// Write a string of characters into the packet
@@ -75,7 +74,7 @@ class UDP : public Stream {
7574

7675
// Start processing the next available incoming packet
7776
// Returns the size of the packet in bytes, or 0 if no packets are available
78-
int parsePacket();
77+
virtual int parsePacket();
7978
// Number of bytes remaining in the current packet
8079
virtual int available();
8180
// Read a single byte from the current packet
@@ -91,9 +90,9 @@ class UDP : public Stream {
9190
virtual void flush(); // Finish reading the current packet
9291

9392
// Return the IP address of the host who sent the current incoming packet
94-
IPAddress remoteIP() { return _remoteIP; };
93+
virtual IPAddress remoteIP() { return _remoteIP; };
9594
// Return the port of the host who sent the current incoming packet
96-
uint16_t remotePort() { return _remotePort; };
95+
virtual uint16_t remotePort() { return _remotePort; };
9796
};
9897

9998
#endif

libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include <SPI.h> // needed for Arduino versions later than 0018
1717
#include <Ethernet.h>
18-
#include <Udp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
18+
#include <EthernetUdp.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
1919

2020

2121
// Enter a MAC address and IP address for your controller below.
@@ -30,8 +30,8 @@ unsigned int localPort = 8888; // local port to listen on
3030
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
3131
char ReplyBuffer[] = "acknowledged"; // a string to send back
3232

33-
// A UDP instance to let us send and receive packets over UDP
34-
UDP Udp;
33+
// An EthernetUDP instance to let us send and receive packets over UDP
34+
EthernetUDP Udp;
3535

3636
void setup() {
3737
// start the Ethernet and UDP:

libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
#include <SPI.h>
2020
#include <Ethernet.h>
21-
#include <Udp.h>
21+
#include <EthernetUdp.h>
2222

2323
// Enter a MAC address for your controller below.
2424
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
@@ -34,7 +34,7 @@ const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the
3434
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
3535

3636
// A UDP instance to let us send and receive packets over UDP
37-
UDP Udp;
37+
EthernetUDP Udp;
3838

3939
void setup()
4040
{

0 commit comments

Comments
 (0)