From bc0f3c4fe165aafe60c4cda254e3d16bb6be69ec Mon Sep 17 00:00:00 2001 From: amcewen Date: Tue, 28 Dec 2010 15:16:42 +0000 Subject: [PATCH] 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. --- libraries/Ethernet/Udp.cpp | 30 ++++++++++++++++--- libraries/Ethernet/Udp.h | 7 +++-- .../UDPSendReceiveString.pde | 2 ++ .../examples/UdpNtpClient/UdpNtpClient.pde | 11 +++++++ 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/libraries/Ethernet/Udp.cpp b/libraries/Ethernet/Udp.cpp index 17eaac69c..b349317d7 100644 --- a/libraries/Ethernet/Udp.cpp +++ b/libraries/Ethernet/Udp.cpp @@ -32,10 +32,25 @@ #include "Udp.h" /* Start UDP socket, listening at local port PORT */ -void UdpClass::begin(uint16_t port) { +uint8_t UdpClass::begin(uint16_t port) { + if (_sock != MAX_SOCK_NUM) + return 0; + + for (int i = 0; i < MAX_SOCK_NUM; i++) { + uint8_t s = W5100.readSnSR(i); + if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) { + _sock = i; + break; + } + } + + if (_sock == MAX_SOCK_NUM) + return 0; + _port = port; - _sock = 0; //TODO: should not be hardcoded socket(_sock, SnMR::UDP, _port, 0); + + return 1; } /* Send packet contained in buf of length len to peer at specified ip, and port */ @@ -129,8 +144,15 @@ port = myPort; return ret; } +/* Release any resources being used by this UdpClass instance */ +void UdpClass::stop() +{ + if (_sock == MAX_SOCK_NUM) + return; + close(_sock); + EthernetClass::_server_port[_sock] = 0; + _sock = MAX_SOCK_NUM; +} -/* Create one global object */ -UdpClass Udp; diff --git a/libraries/Ethernet/Udp.h b/libraries/Ethernet/Udp.h index 5b88d3e06..51c045f20 100644 --- a/libraries/Ethernet/Udp.h +++ b/libraries/Ethernet/Udp.h @@ -45,7 +45,8 @@ private: uint16_t _port; // local port to listen on public: - void begin(uint16_t); // initialize, start listening on specified port + UdpClass() : _sock(MAX_SOCK_NUM) {}; + uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use int available(); // has data been received? // C-style buffer-oriented functions @@ -56,8 +57,8 @@ public: // readPacket that fills a character string buffer int readPacket(char *, uint16_t, uint8_t *, uint16_t &); + // Finish with the UDP socket + void stop(); }; -extern UdpClass Udp; - #endif diff --git a/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde b/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde index cfe1b58b5..6f694d250 100644 --- a/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde +++ b/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde @@ -35,6 +35,8 @@ unsigned int remotePort; // holds received packet's originating port char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet, char ReplyBuffer[] = "acknowledged"; // a string to send back +// A UDP instance to let us send and receive packets over UDP +UdpClass Udp; void setup() { // start the Ethernet and UDP: diff --git a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde index 0b3832b5b..c28e1e02e 100644 --- a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde +++ b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde @@ -37,6 +37,9 @@ const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets +// A UDP instance to let us send and receive packets over UDP +UdpClass Udp; + void setup() { // start Ethernet and UDP @@ -80,8 +83,16 @@ void loop() Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) Serial.print(':'); + if ( ((epoch % 3600) / 60) < 10 ) { + // In the first 10 minutes of each hour, we'll want a leading '0' + Serial.print('0'); + } Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) Serial.print(':'); + if ( (epoch % 60) < 10 ) { + // In the first 10 seconds of each minute, we'll want a leading '0' + Serial.print('0'); + } Serial.println(epoch %60); // print the second } // wait ten seconds before asking for the time again