Skip to content

Commit bc0f3c4

Browse files
committed
Fixes to UDP so that it no longer has socket 0 hardcoded - all part of issue #436. UdpClass::begin now finds the first available free socket, or fails if they're all in use. UdpClass::stop added to release the socket once it is no longer needed. The global Udp object has also been removed and the examples updated to provide their own instance. Finally, in testing I noticed that the UdpNtpClient didn't print leading 0s if the minute or second was a single-digit, so have taken the opportunity to provide a simple fix for it.
1 parent 53f3e8e commit bc0f3c4

File tree

4 files changed

+43
-7
lines changed

4 files changed

+43
-7
lines changed

libraries/Ethernet/Udp.cpp

+26-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,25 @@
3232
#include "Udp.h"
3333

3434
/* Start UDP socket, listening at local port PORT */
35-
void UdpClass::begin(uint16_t port) {
35+
uint8_t UdpClass::begin(uint16_t port) {
36+
if (_sock != MAX_SOCK_NUM)
37+
return 0;
38+
39+
for (int i = 0; i < MAX_SOCK_NUM; i++) {
40+
uint8_t s = W5100.readSnSR(i);
41+
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
42+
_sock = i;
43+
break;
44+
}
45+
}
46+
47+
if (_sock == MAX_SOCK_NUM)
48+
return 0;
49+
3650
_port = port;
37-
_sock = 0; //TODO: should not be hardcoded
3851
socket(_sock, SnMR::UDP, _port, 0);
52+
53+
return 1;
3954
}
4055

4156
/* Send packet contained in buf of length len to peer at specified ip, and port */
@@ -129,8 +144,15 @@ port = myPort;
129144
return ret;
130145
}
131146

147+
/* Release any resources being used by this UdpClass instance */
148+
void UdpClass::stop()
149+
{
150+
if (_sock == MAX_SOCK_NUM)
151+
return;
132152

153+
close(_sock);
133154

155+
EthernetClass::_server_port[_sock] = 0;
156+
_sock = MAX_SOCK_NUM;
157+
}
134158

135-
/* Create one global object */
136-
UdpClass Udp;

libraries/Ethernet/Udp.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ class UdpClass {
4545
uint16_t _port; // local port to listen on
4646

4747
public:
48-
void begin(uint16_t); // initialize, start listening on specified port
48+
UdpClass() : _sock(MAX_SOCK_NUM) {};
49+
uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
4950
int available(); // has data been received?
5051

5152
// C-style buffer-oriented functions
@@ -56,8 +57,8 @@ class UdpClass {
5657
// readPacket that fills a character string buffer
5758
int readPacket(char *, uint16_t, uint8_t *, uint16_t &);
5859

60+
// Finish with the UDP socket
61+
void stop();
5962
};
6063

61-
extern UdpClass Udp;
62-
6364
#endif

libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ unsigned int remotePort; // holds received packet's originating port
3535
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
3636
char ReplyBuffer[] = "acknowledged"; // a string to send back
3737

38+
// A UDP instance to let us send and receive packets over UDP
39+
UdpClass Udp;
3840

3941
void setup() {
4042
// start the Ethernet and UDP:

libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde

+11
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the
3737

3838
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
3939

40+
// A UDP instance to let us send and receive packets over UDP
41+
UdpClass Udp;
42+
4043
void setup()
4144
{
4245
// start Ethernet and UDP
@@ -80,8 +83,16 @@ void loop()
8083
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
8184
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
8285
Serial.print(':');
86+
if ( ((epoch % 3600) / 60) < 10 ) {
87+
// In the first 10 minutes of each hour, we'll want a leading '0'
88+
Serial.print('0');
89+
}
8390
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
8491
Serial.print(':');
92+
if ( (epoch % 60) < 10 ) {
93+
// In the first 10 seconds of each minute, we'll want a leading '0'
94+
Serial.print('0');
95+
}
8596
Serial.println(epoch %60); // print the second
8697
}
8798
// wait ten seconds before asking for the time again

0 commit comments

Comments
 (0)